我们通常遇到optionsCaption绑定的问题:即使只有一个元素,也会显示它。我们使用自定义绑定解决了这个问题:
ko.bindingHandlers.optionsAutoSelect = {
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var allBindings = allBindingsAccessor();
if (value.length == 1) {
allBindings.optionsCaption = null;
}
ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor);
}
};
更新到knockout 3.0之后allBindings变为readonly。因此,任何更改都会被跳过。任何想法如何在ko 3.0中解决?我们确实有很多这样的自动选择,并且不想在所有视图上复制粘贴一些计算代码。所以我们想要一些单选项/扩展点。不幸的是,因为我可以看到选项绑定是相当单一的。
答案 0 :(得分:6)
您可以采取一些不同的方法。这是一个想法(随意使用比optionsPlus
更好的名称):
ko.bindingHandlers.optionsPlus = {
preprocess: function(value, name, addBindingCallback) {
//add optionsCaption to the bindings against a "caption" sub-observable
addBindingCallback("optionsCaption", value + ".caption");
//just return the original value to allow this binding to remain as-is
return value;
},
init: function(element, valueAccessor) {
var options = valueAccessor();
//create an observable to track the caption
if (options && !ko.isObservable(options.caption)) {
options.caption = ko.observable();
}
//call the real options binding, return to control descendant bindings
return ko.bindingHandlers.options.init.apply(this, arguments);
},
update: function(element, valueAccessor, allBindings) {
var options = valueAccessor(),
value = ko.unwrap(options);
//set the caption observable based on the length of data
options.caption(value.length === 1 ? null : allBindings.get("defaultCaption"));
//call the original options update
ko.bindingHandlers.options.update.apply(this, arguments);
}
};
您可以使用它:
<select data-bind="optionsPlus: choices, defaultCaption: 'choose one...'"></select>
它会从您的observableArray /数组创建一个caption
observable,并在更新选项时更新标题(如果使用observableArray)。