只是发现淘汰赛,所以如果我在这里错过了一些事情,请指出愚蠢。我目前有一个多重选择绑定到可观察的淘汰赛中。
<select class="form-control" id="SithSelect" data-bind="attr: { 'data-has-value': (Sith() ? true : false) }, selectedOptions: Sith() ? Sith().split('|') : '' " placeholder="The dark side" multiple>
<option disabled></option>
<option value="Darth Vader">Darth Vader</option>
<option value="Darth Maul">Darth Maul</option>
<option value="Darth Bane">Darth Bane</option>
</select>
其中“ Sith”是可观察的字符串值。
当我在数据库中手动添加字符串值“ Darth Vader | Darth Maul”,并且该值最终下降到客户端时,多选正确显示了两个选定的值。
但是,如果更改值,那么如何将选择的值组合回到可观察对象中存储的管道定界字符串中?
根据我的尝试,可以通过将选择绑定到一个可观察的数组来对它进行排序,然后在保存到数据库时重新构造管道分隔的字符串。当我查看代码时,此解决方案有点可笑,因为它感觉与各个select元素紧密耦合(这是页面上唯一使用数据库中以竖线分隔的字符串的元素)。
我是否错过了在多重选择和定界字符串之间进行双向绑定的某些事情?相反,有没有办法做相反的事情
selectedOptions: Sith() ? Sith().split('|') : ''
将多个选定选项分配回绑定中的可观察值时?
更新:问题已缩小为:
是否有内置的敲除函数可以放置在绑定中,可以处理计算值的读/写功能,以便可以内联写入,而不必创建单独的计算可观察值?
最佳答案
selectedOptions
应该是数组或可观察的数组。 http://knockoutjs.com/documentation/selectedOptions-binding.html
当您将根据Sith
计算出的一些数据传递给它时,淘汰赛无法知道如何将数据保存回Sith
。
您应该使用ko.observableArray
或仅将ko.observable
与数组值一起使用。但是,您需要同步字符串值和数组值。可以使用可写计算(http://knockoutjs.com/documentation/computed-writable.html)来代替手动支持两个订阅(str => arr,arr => str):
<select data-bind="selectedOptions: sith">...</select>
vm.sithString = ko.observable('');
vm.sith = ko.computed({
read: function() { return vm.sithString().split('|'); },
write: function(arr) { vm.sithString(arr.join('|')); }
});
更新
是否有内置的敲除函数可以放置在绑定中,可以处理计算值的读/写功能,以便可以内联写入,而不必创建单独的计算可观察值?
这是MVVM中ViewModel的确切目的。您有模型,它是纯数据(嗯,无论如何,您都必须将其存储在可观察对象中)。您有绑定,这纯粹是UI的事情。并且您在它们之间具有调解器ViewModel来在它们之间转换数据和事件。在此示例中计算得出的可写表示ViewModel-Model关系。
每个绑定中的可写计算比
write
/ read
函数更通用和更灵活。更新2
好吧,
selectedOptions
并不是最简单的绑定方法。方法是将完全相同的计算结果附加到元素,并在绑定函数中替换valueAccessor
。代码很简单,但是需要知道binging如何工作:var selectedOptions = ko.bindingHandlers['selectedOptions'];
ko.bindingHandlers['pipedOptions'] = {
after: selectedOptions.after, /* ['options', 'foreach'] */
init: function(el, va) {
var obsv = va();
var mediator = ko.computed({
read: function() { return obsv().split('|'); },
write: function(arr) { obsv(arr.join('|')); }
});
ko.utils.domData.set(el, 'pipedOptions.mediator', mediator);
var args = [].slice.call(arguments);
args[1] = function() { return mediator; };
selectedOptions.init.apply(this, args);
},
update: function(el, va) {
var mediator = ko.utils.domData.get(el, 'pipedOptions.mediator');
var args = [].slice.call(arguments);
args[1] = function() { return mediator; };
selectedOptions.update.apply(this, args);
}
};
如果您需要更复杂的行为,请查看组件。