自定义绑定不再适用于KnockoutJS 3.0

时间:2013-11-21 01:01:03

标签: javascript mvvm knockout.js knockout-3.0

突然之间,以下代码在定位KnockoutJS 3.0时不再有效。我该如何解决这个问题?

JavaScript的:

ko.bindingHandlers.limitCharacters = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel)
    {
       element.value = element.value.substr(0, valueAccessor());
       allBindingsAccessor().value(element.value.substr(0, valueAccessor()));
    }
};

HTML:

<textarea data-bind="value: comment, valueUpdate: 'afterkeydown', limitCharacters: 20"></textarea>

请参阅小提琴:http://jsfiddle.net/ReQrz/1/

2 个答案:

答案 0 :(得分:6)

在KO 3.0中,绑定是独立的并且是有序的。您可以阅读有关此here的更多信息,这应该被视为“突破性变化”,来自上面的链接示例:

  

v2.x关于绑定之间依赖关系的行为(在   关于“独立和有序绑定”的部分,是一个   未记录的内部实施细节所以希望你不是   依靠它。但如果你依赖于那么显然你会   看到行为的变化,因为绑定在v3中是独立的   设计。您需要停止依赖交叉绑定依赖项,   顺便说一句,这将使您的代码更清洁,更容易   理解。

所以你的绑定不再起作用,因为它假设当你的comment属性发生变化时,你的limitCharacters binging limitCharacters绑定你的comment绑定与{value绑定无关1}}属性。

解决此问题的一种可能解决方案是,您需要通过使用update访问其allBindingsAccessor().value();来明确声明ko.bindingHandlers.limitCharacters = { update: function(element, valueAccessor, allBindingsAccessor, viewModel) { var val = allBindingsAccessor().value(); allBindingsAccessor().value(val.substr(0, valueAccessor())); } }; 处理程序中{{1}}绑定的依赖关系:

{{1}}

演示JSFiddle

答案 1 :(得分:1)

nemesv是完全正确的。

他的修改简短易读。这样做的一个缺点是,当超过限制时,可观察到的被调用两次。

如果您不想这样,解决方案是创建一个源自原始的自定义值绑定器。

(function() {
    var limitValueBindingHandler = {};

    var valueBindingHandler = ko.bindingHandlers.value;
    for(var attr in valueBindingHandler) {
        if (valueBindingHandler.hasOwnProperty(attr)) {
            limitValueBindingHandler[attr] = valueBindingHandler[attr];
        }
    }

    limitValueBindingHandler.init = function(element, valueAccessor, allBindings) {
        var limitCharacters = allBindings.get("limitCharacters");

        element.addEventListener("keydown", function() {
            setTimeout(function() {
                //this is called after the element's value is updated
                //but before value binding event handler
                element.value = element.value.substr(0, limitCharacters);
            }, 0);
        }, false);

        valueBindingHandler.init(element, valueAccessor, allBindings);
    }

    ko.bindingHandlers['limitValue'] = limitValueBindingHandler;
})();

示例:http://jsfiddle.net/DAFN6/