2017-02-08 86 views
1

当使用select和knockouts'选项'绑定时,我看到隐藏select元素并再次显示时的行为。Knockout选项选择在隐藏/显示后重新初始化

当我在列表中选择一个选项时,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),可观察值将获取该值。当您取消选中可见并隐藏选择框并再次使其可见时,它将丢失其所选值并重新初始化为列表中的第一项。

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

+0

是否有一个特定的原因,你需要一个可写的计算Observable属性?另外,在计算的observable里面的'read'函数中,你没有返回任何值,所以什么都不会设置。 – Agalo

回答

1

由于您将select绑定到缺少背景字段的计算器,因此UI无法保存其状态。通常情况下,您将有一个可观察的存储区当前选定的值,并且计算结果仅用于对后台字段和UI之间的数据执行一些转换。

如果添加一个observable并将其值传递给calculate,那么select将保存其状态,并在通过'if'绑定重新添加后重新绑定到最后一个值,因为它将被重新绑定 - 用observable的保存值初始化。

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); 
}); 
+0

谢谢。我应该提到我想根据select的新值进行一些更改。但是,这应该只在用户修改所选值时发生,而不是因为它正在加载到dom中。使用第二个可观察值并不能真正解决这个问题,因为我们仍然不知道是什么导致了新值的设置。 – Consec

+0

你有没有尝试添加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中的包含标记, 并且仅在表达式为true时才将绑定应用于后代。