如何使用扩展器中的扩展器将元素id绑定到observable?

时间:2013-05-04 19:31:57

标签: jquery-mobile checkbox knockout.js custom-binding

我有一组复选框,每个复选框都绑定到一个自定义的“已检查”处理程序:

    <input type="checkbox" name="colours-red" data-bind="jqmCheckbox: colourRed" id="check-1" />
    <input type="checkbox" name="colours-green" data-bind="jqmCheckbox: colourGreen" id="check-2" />
    <input type="checkbox" name="colours-blue" data-bind="jqmCheckbox: colourBlue" id="check-3" />

我的视图模型非常简单:

this.colourRed = ko.observable(false);
this.colourGreen = ko.observable(false);
this.colourBlue = ko.observable(false);

现在,我尝试按如下方式扩展颜色,以使其自动更新。 如果发生变化,我需要其他订阅者收到通知:

ko.extenders.elementId = function (target, option) {
    target.elId = ko.observable();

    function setElementId(target, option) {
        target.elId(option);
    }
    target.subscribe(setElementId);
    return target;
};

在自定义绑定中,我可以获得元素id:

ko.bindingHandlers.jqmCheckbox = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.bindingHandlers.checked.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
        // ...set this valueAccessor extender ?
    }
};

但是我无法让它工作,而且我也不知道这是否可行。 如何在自定义绑定处理程序中设置扩展程序,其中元素可用作参数?

这是jsFiddle:http://jsfiddle.net/Tk2FZ/1/

提前致谢

2 个答案:

答案 0 :(得分:1)

我不打算使用扩展器;只需在绑定处理程序中设置elId属性。

ko.bindingHandlers.jqmCheckbox = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        if (!valueAccessor().elId) {
            valueAccessor().elId = ko.observable();
        }
        valueAccessor().elId(element.id);
        return ko.bindingHandlers.checked.init.apply(this, arguments);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        return ko.bindingHandlers.checked.update.apply(this, arguments);
    }
};

代码在init内部,因为在特定元素上初始化绑定时会调用该代码。

修改

如果您需要立即使用observable,您可以使用扩展器(除了上面的代码)。然后在初始化绑定时更新observable。

ko.extenders.elementId = function (target, option) {
    target.elId = ko.observable();
    return target;
};

答案 1 :(得分:0)

<强>解决: 经过一段时间再次使用后,我发现了问题。 这是最后的工作小提琴:http://jsfiddle.net/z9qZc/

我把这个答案给了我自己,以防万一这两分钱可以帮助别人腾出时间。 我发现这个扩展器是一个通用的解决方案,也许并不是那么糟糕。 让我知道你的想法。

答案是(现在)明确:初始化扩展器(因为在大多数情况下,只需要小心阅读文档就足够了......)。

self.colourRed = ko.observable(true).extend({elementId:""});
self.colourGreen = ko.observable(false).extend({elementId:""});
self.colourBlue = ko.observable(false).extend({elementId:""});

感谢Cyanfish指出我的第一次尝试是用不必要的代码臃肿,并帮助了我很多。 感谢所有淘汰的人,他们制作了这件精美的艺术品来帮助我们所有人。