突然之间,以下代码在定位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/
答案 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;
})();