淘汰赛:如何从自定义绑定更新另一个绑定?

时间:2013-12-06 14:08:26

标签: knockout.js ko-custom-binding

我们通常遇到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中解决?我们确实有很多这样的自动选择,并且不想在所有视图上复制粘贴一些计算代码。所以我们想要一些单选项/扩展点。不幸的是,因为我可以看到选项绑定是相当单一的。

1 个答案:

答案 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)。

此处示例:http://jsfiddle.net/rniemeyer/jZ2FC/

相关问题