gpt4 book ai didi

javascript - Knockout JS 设置 optionsValue 破坏了我的代码

转载 作者:行者123 更新时间:2023-12-02 18:52:04 25 4
gpt4 key购买 nike

下面的代码经过简化,请参阅 fiddle :http://jsfiddle.net/QTUqD/7/

基本上我是在数据绑定(bind)下设置设备名称,但我还需要指定发送到数据库的选项值,但是当我设置它时,显示数据绑定(bind)为空。

<script id="extItems" type="text/html">
<tr>
<td data-bind="text: device() && device().name"></td>
</tr>
</script>

<script id="editExts" type="text/html">
<tr>
<td>

<select data-bind="options: $root.devicesForItem($data), optionsText: 'name', value: device, optionsValue: 'id'"></select>

</td>
</tr>
</script>
<小时/>
    window.ExtListViewModel = new function () {
var self = this;
window.viewModel = self;

self.list = ko.observableArray();

self.pageSize = ko.observable(10);
self.pageIndex = ko.observable(0);
self.selectedItem = ko.observable();
self.extQty = ko.observable();
self.devices = ko.observableArray();
self.addressList = ko.observableArray(['addressList']);
self.availableDevices = ko.computed(function() {
var usedQuantities = {}; // for each device id, store the used quantity
self.list().forEach(function(item) {
var device = item.device();
if (device) {
usedQuantities[device.id] = 1 + (usedQuantities[device.id] || 0);
}
});

return self.devices().filter(function(device) {
var usedQuantity = usedQuantities[device.id] || 0;
return device.qty > usedQuantity;
});
});

// need this to add back item's selected device to its device-options,
// and to maintain original order of devices
self.devicesForItem = function(item) {
var availableDevices = self.availableDevices();
return self.devices().filter(function(device) {
return device === item.device() || availableDevices.indexOf(device) !== -1;
});
}

self.edit = function (item) {
if($('#extMngForm').valid()) {
self.selectedItem(item);
}
};

self.cancel = function () {
self.selectedItem(null);
};

self.add = function () {
if($('#extMngForm').valid()) {
var newItem = new Extension();
self.list.push(newItem);
self.selectedItem(newItem);
self.moveToPage(self.maxPageIndex());
}
};
self.remove = function (item) {

if (confirm('Are you sure you wish to delete this item?')) {

self.list.remove(item);
if (self.pageIndex() > self.maxPageIndex()) {
self.moveToPage(self.maxPageIndex());
}

}
$('.error').hide();
};
self.save = function () {
if($('#extMngForm').valid()) {
self.selectedItem(null);
};
};

self.templateToUse = function (item) {
return self.selectedItem() === item ? 'editExts' : 'extItems';
};

self.pagedList = ko.dependentObservable(function () {
var size = self.pageSize();
var start = self.pageIndex() * size;
return self.list.slice(start, start + size);
});
self.maxPageIndex = ko.dependentObservable(function () {
return Math.ceil(self.list().length / self.pageSize()) - 1;
});
self.previousPage = function () {
if (self.pageIndex() > 0) {
self.pageIndex(self.pageIndex() - 1);
}
};
self.nextPage = function () {
if (self.pageIndex() < self.maxPageIndex()) {
self.pageIndex(self.pageIndex() + 1);
}
};
self.allPages = ko.dependentObservable(function () {
var pages = [];
for (i = 0; i <= self.maxPageIndex() ; i++) {
pages.push({ pageNumber: (i + 1) });
}
return pages;
});
self.moveToPage = function (index) {
self.pageIndex(index);
};


};

ko.applyBindings(ExtListViewModel, document.getElementById('extMngForm'));

function Extension(extension, name, email, vmpin, device, macAddress, shipTo){
this.extension = ko.observable(extension);
this.name = ko.observable(name);
this.email = ko.observable(email);
this.vmpin = ko.observable(vmpin);
this.device = ko.observable(device);
this.macAddress = ko.observable(macAddress);
this.shipTo = ko.observable(shipTo);
}

最佳答案

当您使用optionsValue时,KO会将属性值写入您针对value绑定(bind)的任何内容。因此,它现在将使用 id 而不是对象来填充值。

有几种方法可以解决这种情况,即您既需要值(用于发送到数据库)又需要对象(用于绑定(bind) UI 的其他部分)。

一个非常典型的解决方案是在对象上创建一个计算的可观察对象,该对象获取当前选定的对象并返回 id。

因此,在您的扩展中,您将执行以下操作:

this.device = ko.computed({
read: function() {
var device = this.device.asObject();
return device && device.id;
},
deferEvaluation: true, //deferring evaluation, as device.asObject has not been created yet
}, this);

//create this as a sub-observable, so it just disappears when we turn this into JSON and we are just left with the id to send to the DB
this.device.asObject = ko.observable(device);

然后删除 optionsValue 并将 value 绑定(bind)到 device.asObject

在本例中,我添加了 asObject 子可观察对象,因此当您将其转换为 JSON (ko.toJSON) 发送到服务器。此技术唯一棘手的部分是,如果您要从服务器加载现有数据,则需要使用选项中的适当选择来填充 asObject

这是一个示例:http://jsfiddle.net/rniemeyer/Q3PEv/

我使用的另一个选项是继续使用 optionsValue,但随后创建一个自定义绑定(bind)来跟踪单独的可观察对象中的对象。这是一个自定义绑定(bind),它为与 value 绑定(bind)的任何内容创建一个 asObject 子可观察对象。这样你就真的不需要在 View 模型中搞乱它了。

//when using optionsValue, still track the select object in a different observable
ko.bindingHandlers.valueAsObject = {
init: function(element, valueAccessor, allBindingsAccessor) {
var value = allBindingsAccessor().value,
prop = valueAccessor() || 'asObject';

//add an "asObject" sub-observable to the observable bound against "value"
if (ko.isObservable(value) && !value[prop]) {
value[prop] = ko.observable();
}
},
//whenever the value or options are updated, populated the "asObject" observable
update: function(element, valueAccessor, allBindingsAccessor) {
var prop = valueAccessor(),
all = allBindingsAccessor(),
options = ko.utils.unwrapObservable(all.options),
value = all.value,
key = ko.utils.unwrapObservable(value),
keyProp = all.optionsValue,
//loop through the options, find a match based on the current "value"
match = ko.utils.arrayFirst(options, function(option) {
return option[keyProp] === key;
});

//set the "asObject" observable to our match
value[prop](match);
}
};

示例:http://jsfiddle.net/rniemeyer/E2kvM/

关于javascript - Knockout JS 设置 optionsValue 破坏了我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15719298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com