简体   繁体   English

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

[英]Custom binding no longer working in KnockoutJS 3.0

All of the sudden, the following code no longer works when targeting KnockoutJS 3.0. 突然之间,以下代码在定位KnockoutJS 3.0时不再有效。 How can I work around this? 我该如何解决这个问题?

JavaScript: 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: HTML:

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

See fiddle: http://jsfiddle.net/ReQrz/1/ 见小提琴: http//jsfiddle.net/ReQrz/1/

In KO 3.0 the bindings are Independent and ordered. 在KO 3.0中,绑定是独立的并且是有序的。 You can read more about this here , and this should be considered a "breaking change", from the above linked example: 您可以在这里阅读更多相关信息,这应该被视为一个“突破性变化”,来自上面的链接示例:

v2.x's behavior about dependencies between bindings (described in the section about “Independent and ordered bindings” above), is an undocumented internal implementation detail so hopefully you aren't relying on it. v2.x关于绑定之间依赖关系的行为(在上面的“独立和有序绑定”一节中描述)是一个未记录的内部实现细节,所以希望你不依赖它。 But if you are relying on that then obviously you will see a change of behavior because bindings are independent in v3 by design. 但是如果你依赖于那么显然你会看到行为的改变,因为绑定在v3中是独立的设计。 You'll need to stop relying on cross-binding dependencies, which by the way will make your code much cleaner and easier to understand. 您需要停止依赖交叉绑定依赖项,这样可以使您的代码更清晰,更易于理解。

So you binding is not working anymore because it assumed that when your comment property is changed it fires also your limitCharacters binging altough your limitCharacters binding has nothing to do with the comment property. 所以你的绑定不再起作用了,因为它假设当你的comment属性被改变时它也会触发你的limitCharacters你的limitCharacters绑定与comment属性无关。

One possible solution for fixing this that you need to explicitly declare a dependency on the value binding in your update handler by acessing its value with allBindingsAccessor().value(); 解决此问题的一种可能解决方案是,您需要通过使用allBindingsAccessor().value();其值来显式声明update处理程序中value绑定的依赖关系allBindingsAccessor().value(); :

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

Demo JSFiddle . 演示JSFiddle

nemesv is completely right. nemesv是完全正确的。

His modification is short and easy to read. 他的修改简短易读。 One drawback of that though is the observable is called twice when in exceeds the limit. 然而,一个缺点是当超过极限时,可观察到被调用两次。

If you don't want that, a solution is to create a custom value binder which derives from the original. 如果您不想这样,解决方案是创建一个源自原始的自定义值绑定器。

(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;
})();

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM