当使用select with knockouts'选项'绑定时,我看到隐藏select元素并再次显示时我没想到的行为。
当我在列表中选择一个选项时,observable被赋予正确的值。但是,当我隐藏选择的html项目然后再次使其可见时,之前选择的值将丢失。
对于我的测试,我使用以下html模板:
Visible: <input type="checkbox" data-bind="checked: visible" />
<!-- ko 'if': visible -->
<select data-bind="options: options, optionsText: 'name', value: selectedItem"></select>
<!-- /ko -->
与
结合使用var ViewModel = function() {
this.visible = ko.observable(true);
this.options = ko.observableArray([
{name: 'A', value: 'A00'},
{name: 'B', value: 'A01'},
{name: 'C', value: 'A02'},
]);
this.selectedItem = ko.computed({
read: function () {
console.log("reading value");
},
write: function (newSelection) {
console.log("setting value:" + newSelection.value);
}
});
};
ko.applyBindings(new ViewModel());
你可以在jsfiddle的例子中测试这个: http://jsfiddle.net/5wZQ2/169/
当您选择一个值(例如列表中的B)时,observable将获取该值。当您取消选中可见并隐藏选择框然后再次显示它时,它将丢失其选定的值并重新初始化为列表中的第一个项目。
有人可以解释这种行为吗?
答案 0 :(得分:1)
如果将if绑定更改为可见绑定,则会发生预期的行为。在这里看到你的更新小提琴。 http://jsfiddle.net/5wZQ2/171/
Visible: <input type="checkbox" data-bind="checked: visible" />
<div data-bind="visible: visible">
<select data-bind="options: options, optionsText: 'name', value: selectedItem"></select>
</div>
我认为差异在文件http://knockoutjs.com/documentation/if-binding.html中说明了
如果扮演与可见绑定类似的角色。不同的是 可见,包含的标记始终保留在DOM中 始终应用其数据绑定属性 - 仅可见绑定 使用CSS来切换容器元素的可见性。 if绑定, 但是,在DOM中物理添加或删除包含的标记, 并且只有在表达式为真时才对后代应用绑定。
答案 1 :(得分:1)
由于您将select绑定到缺少支持字段的computed,因此UI无法保存其状态。通常,您将拥有一个可观察存储的当前选定值,并且计算仅用于对支持字段和UI之间的数据执行某些转换。
如果你添加一个observable,并通过计算器传递它的值,那么select将保存其状态并在被删除后重新绑定到最后一个值,并通过'if'绑定重新添加,因为它将重新用可观察的保存值初始化。
this._selectedItem = ko.observable();
this.selectedItem = ko.computed({
read: function () {
console.log("reading value");
return this._selectedItem();
},
write: function (newSelection) {
console.log("setting value:" + newSelection.value);
this._selectedItem(newSelection);
}
}, this);
在您的示例中,根本没有理由使用计算机。您可以将select绑定到普通的observable。
this.selectedItem = ko.observable();
然后,如果您仍希望将更改记录到控制台,则可以在observable上使用subscribe方法。
this.selectedItem.subscribe(function(newSelection){
console.log("setting value:" + newValue);
});