Knockout选项选择隐藏/显示后重新初始化

时间:2017-02-08 01:03:08

标签: javascript html knockout.js

当使用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将获取该值。当您取消选中可见并隐藏选择框然后再次显示它时,它将丢失其选定的值并重新初始化为列表中的第一个项目。

有人可以解释这种行为吗?

2 个答案:

答案 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);
});
相关问题