SELECT with 2 optgroups build with KnockOut将值重置为空



我有这个HTML

<select data-bind="value: $data.id">
<optgroup label="Regions" data-bind="foreach: countries.regions.names">
<option data-bind="html: $data.name, value: $data.value"></option>
</optgroup>
<optgroup label="Countries" data-bind="foreach: shipping.allCountries">
<option data-bind="html: $data.name, value: $data.code"></option>
</optgroup>
</select>

有了这个javascript,它在两个optgroups中的任何一个中都预先填充了一个ID。ID始终存在!

this.id = ko.observable(data.id);

但是在KnockOut构建select之后,this.id()的值为空,并且将返回undefined。当我订阅该字段时,它会通知我它正在更新,但没有任何内容。

我当前的(脏)修复:

setTimeout(function(){
self.id(data.id);
}, 500);

这是有效的,但当然不推荐。

此外,在select中选择另一个元素并返回到原始值后,也可以。

如何解决此问题?

注意:选择了正确的元素

失败的原因是<select>元素的value在使用foreach绑定其内容之前被绑定,并且如果模型值本身无法选择,value绑定将把模型值重置为元素中当前选择的值。

问题示例:http://jsfiddle.net/mbest/8r6KY/

对此有两种解决方案。

1.防止模型值重置

一种解决方案是使用Knockout 3.1(目前处于Beta版)中提供的新绑定选项valueAllowUnset来防止value绑定重置模型值。

<select data-bind="value: $data.id, valueAllowUnset: true">

示例:http://jsfiddle.net/mbest/D6dR2/

2.先绑定内容后绑定值

第二种解决方案是在绑定value之前将<option>元素放置到位。这可以通过对元素进行自定义绑定来完成,该元素可以早期绑定内容。

<select data-bind="bindInner, value: $data.id">

绑定:

ko.bindingHandlers.bindInner = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
ko.applyBindingsToDescendants(bindingContext, element);
return { controlsDescendantBindings: true };
}
};

示例:http://jsfiddle.net/mbest/ETFsa/

建议

第一个选项使用内置解决方案,但有一个缺点,即UI选择使用setTimeout(在value绑定内)。因此,在视图初始化时,您可以在选择中进行可见的更改。我认为,第二种选择是更好的,尽管你当然可以同时使用这两种方法来双重解决问题。

确保您的countries.regions.names实际指向正确的位置。如果这些选项不存在,那么这些值就不存在。

最新更新