调用默认敲除绑定时,自定义Knockout绑定失败

时间:2012-10-31 15:26:59

标签: knockout.js

概述

创建包含对敲除默认绑定的调用的knockout custom binding时,我的自定义绑定在第一次调用后停止工作。

要查看问题,请在JSFiddle example中更改ddl中的所选项目一次。文本按预期更改。再改变它,没有任何反应。失败。

详情

在使用我自己的自定义绑定“htmlFade”扩展默认的敲除绑定“html”时,我看到了一些奇怪的行为。我正在寻找的行为与html binding相同,但使用JQuery淡入淡出动画来淡入和淡出DOM元素。

以下代码示例。一个完整的JSFiddle示例可以是here

HTML看起来像这样:

<select data-bind="options: names, value: selectedName"></select>  
<data-bind="htmlFade : selectedName" class="main"></div>

Json Data看起来像这样:

var viewModel = {
    names: ko.observableArray(['Bob', 'Jon']),
    selectedName: ko.observable('Bob')
};

Custom Binding看起来像这样:

ko.bindingHandlers.htmlFade = {
    init: function(element, valueAccessor) {
        ko.bindingHandlers.html.init();
        $(element).hide();
    },
    update: function(element, valueAccessor) {
        $(element).fadeOut(700, function() {
           ko.bindingHandlers.html.update(element, valueAccessor);           
           $(element).fadeIn(700);
        });        
    }
};

我故意推迟使用行“ko.bindingHandlers.html.update(element,valueAccessor)”的默认html处理程序,因为我的目标是扩展行为,而不是重新创造。

问题我遇到的是上面的代码在第一次更改选择列表时有效。之后就失败了。

我创建了另一个JSFiddle example,而不是扩展行为,我通过添加以下行重新创建它“http://jsfiddle.net/jamshall/kYwEE/1/”(从knockout source for the default html binding复制而不是上面引用的 html.update 调用。这似乎工作正常。

我的问题,那么,为什么我的自定义绑定在第一次调用后停止工作时,我包含对默认绑定的调用?或者,为简单起见,为什么JSFiddle1无效,JSFiddle2无效?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您可以将自定义绑定的update函数视为计算的observable(Knockout在执行元素绑定时使用计算的observable来跟踪依赖关系)。因此,在您的自定义绑定中,您没有获取对您所绑定的observable的依赖性,因为您的代码是异步执行的。

update中,您可能希望执行以下操作:

update: function(element, valueAccessor) {
    //just grab dependency
    ko.utils.unwrapObservable(valueAccessor());

    $(element).fadeOut(700, function() {
       ko.bindingHandlers.html.update(element, valueAccessor);           
       $(element).fadeIn(700);
    });        
}

因此,我们只需访问observable的值来获取依赖项。 ko.utils.unwrapObservable只是安全地处理检索值,无论它是不可观察的还是可观察的。

更新了示例:http://jsfiddle.net/rniemeyer/6UtsP/10/