我有两个相同的绑定处理程序,其中一个没有触发,因为它没有ko.unwrap(valueAccessor());在“更新:”部分。
看看发生了什么的最好方法是看我的jsfiddle。通过单击按钮,第一个跨度可切换背景,而第二个则不会。
当取消注释第26行时,“ ko.unwrap(valueAccessor());”调用第二次更新功能,另一个跨度切换为灰色/白色。
HTML:
<button id='ChangeValue'>item++</button>
<hr/>
<span>Update fired viewModel.item = </span>
<span data-bind='text: $data.item(), bind1: $data.item'></span>
<br/>
<span>Update not fired viewModel.item = </span>
<span data-bind='text: $data.item(), bind2: $data.item'></span>
JS / jQuery /淘汰赛:
$(document).ready(function() {
$('#ChangeValue').click(function() {
viewModel.item(viewModel.item() + 1);
});
var viewModel = {
item: ko.observable(1)
};
ko.bindingHandlers.bind1 = {
init: function(element, valueAccessor) {
},
update: function(element, valueAccessor) {
ko.unwrap(valueAccessor());
if (element.style.background == "gray") {
element.style.background = "white";
} else {
element.style.background = "gray";
}
}
};
ko.bindingHandlers.bind2 = {
init: function(element, valueAccessor) {
},
update: function(element, valueAccessor) {
// if uncomment following line "update" is called
//ko.unwrap(valueAccessor());
if (element.style.background == "gray") {
element.style.background = "white";
} else {
element.style.background = "gray";
}
}
};
ko.applyBindings(viewModel);
});
这是预期的行为吗?我的真实代码中具有复杂的更新功能,并且想知道为什么某些绑定处理程序没有触发,并且经过长时间的研究,我确实提取了此示例。
我认为这与浏览器中的垃圾收集器(在chrome / IE 11中测试)或敲除有关。
所以我的问题是:
添加“ ko.unwrap(valueAccessor());”是否足够?在我的自定义绑定的更新部分中,以确保将其处理?
是否有任何相关文档?因为我在knockout.js上找不到任何东西
最佳答案
是的,这是预期的行为。每当应用绑定时,都会调用update
方法,并且在执行时,敲除寄存器/跟踪在update方法中访问的observables
。因此,在您的情况下,bind2
绑定不会访问valueAccessor值,因此不会触发任何更新。所以如果你有
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
这使敲除能够在可观察到的
update
的任何变化上触发valueAccessor()
。如果访问
observable
函数中任何update
的值,则该可观察值的更改将触发update
函数。here有据可查。