我正在使用KnockoutJS来管理我的网络前端。我正在编写一个CRUD / Admin站点,但我遇到了selectedOptions绑定问题。
案例:
视图模型包含form.products.all
和form.products.selected
个可观察对象。这两个都是由ko.mapping
生成的。
HTML表单有多种形式选择:
<select required="" multiple="" data-bind="options: products.all, optionsText: function (item) { return item.value.name.unName(); }, selectedOptions: products.selected" class="form-control">
HTML表单正确显示了所有选项。
HTML表单不在加载时显示所选选项。特别是,如果我检查viewModel对象,我可以看到正确的对象在加载时被加载到products.selected
数组中。但是多选不会自动选择它们。
如果我在表单中选择对象然后检查products.selected
可观察对象,我执行查看数组中的对象。
如果我发布表单,正确的对象最终会进入数据库,然后在下一页加载的viewModel对象中结束(因此循环中唯一缺少的部分实际上是基于表单标记表单) products.selected
。
我做错了什么?我看到了相互矛盾的建议,其中一些已经过时,所以我不确定如何继续。
答案 0 :(得分:2)
selectedOptions
绑定按设计工作。
您的selected
observable很可能不包含相同的对象(即引用到all
中的对象) ,但仅仅是具有相同属性值的对象。
Knockout通过对象标识维护绑定,它不进行任何其他比较。
考虑这个简单的例子:
var vm = {
products: {
selected: ko.observableArray(),
all: ko.observableArray([
{
value: {
name: {
unName: ko.observable("Foo")
}
}
}, {
value: {
name: {
unName: ko.observable("Bar")
}
}
}
])
}
};
vm.products.selected.push(vm.products.all()[1]);
ko.applyBindings(vm);
pre {
font-size: small;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<select required="" multiple="" class="form-control" data-bind="
options: products.all,
optionsText: function (item) {
return item.value.name.unName();
},
selectedOptions: products.selected
"></select>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
不相关的附注:尽量避免在绑定属性中定义函数。它是丑陋的,低效的,可能重复的,并不是非常惯用的。在视图模型上创建相应的属性,例如:
function Product(data) {
ko.utils.extend(this, data);
this.displayName = this.value.name.unName;
}
和
<div data-bind="with: products">
<select required="" multiple="" class="form-control" data-bind="
options: all,
optionsText: 'displayName',
selectedOptions: selected
"></select>
</div>