knockoutjs绑定处理程序仅在ko.unwrap(valueAccessor())时触发;正在更新:部分

时间:2015-09-20 12:44:16

标签: javascript html knockout.js

我有两个相同的绑定处理程序,其中一个没有触发,因为它没有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的/ knockoutjs:

$(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中测试)或者淘汰赛有关。

所以我的问题:

  1. 是否应该添加“ko.unwrap(valueAccessor());”在我的自定义绑定的更新部分,以确保它将被处理?
  2. 有关于此的文件吗?因为我在knockout.js
  3. 找不到任何内容

1 个答案:

答案 0 :(得分:1)

  1. 是的,这是预期的行为。每当应用绑定时都会调用update方法,并且在执行时,knockout注册/跟踪在update方法中访问的observables。因此,在您的情况下,bind2绑定不访问valueAccessor值,因此不会触发任何更新。所以,如果你有

    var value = valueAccessor();
    var valueUnwrapped = ko.unwrap(value);
    

    这使得knockout可以在update可观察的任何变化上触发valueAccessor()

    如果您访问observable函数中任何update的值,则该observable的更改将触发update函数。

  2. 记录良好here