Knockout Binding不会初始化,从更新开始

时间:2012-06-06 21:28:49

标签: javascript data-binding initialization knockout.js

我有这两个绑定使用相同的init代码,并绑定到相同的值,但它们不是相同的初始化。第一个正常运行,第二个运行其更新而不是init。这是绑定:

    function initToggle(element, valueAccessor) {
    // Initially set the element to be instantly visible/hidden depending on the value
    var value = valueAccessor();
    $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
};

//Binding Handlers
ko.bindingHandlers.fadeVisible = {
    init: initToggle,
    update: function (element, valueAccessor) {
        // Whenever the value subsequently changes, slowly fade the element in or out
        var value = valueAccessor();
        ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
    }
};

ko.bindingHandlers.slideVisibleVertical = {
    init: initToggle,
    update: function(element, valueAccessor, allBindingsAccessor) {        
        var value = valueAccessor(); //Lastest binding value
        var allBindings = allBindingsAccessor(); //other bindings, allows options

        var valueUnwrapped = ko.utils.unwrapObservable(value); 
        var duration = allBindings.slideDuration || 400; // 400ms is default duration unless otherwise specified

        if (valueUnwrapped == true)
             $(element).show('slide', {direction: 'up'}, duration);
        else
            $(element).hide('slide', {direction: 'up'}, duration);
    }
};

字面意思,相同的init函数。这是a fiddle显示两个按钮,两个按钮绑定到相同的值。 fadeVisible如图所示开始,但slidevisibleVertical会滑入。更新时都会显示动画。有谁知道这里发生了什么?

2 个答案:

答案 0 :(得分:4)

update函数也始终第一次运行。

对于你的fadeVisible,该元素已经可见,因此将其淡化将无法执行任何操作。

对于调用slide的其他绑定,它仍然会为其设置动画,即使它已显示。

您可以采用的一些不同方式:

  • 在元素上存储内容($ data)以指示您在第一次传递时将其清除为更新结束(反之亦然)
  • 在滑动前检查可见性(如您在评论中所述)

答案 1 :(得分:1)

为了澄清已接受的答案关于在元素上存储内容的评论($ data),这里是示例代码:

ko.bindingHandlers.myHandler = {
    init: function (element, valueAccessor) {
        $(element).data("isFirstPass", true);
    },
    update: function (element, valueAccessor) {
        // Always unwrap so that ko tracks the dependency
        ko.unwrap(valueAccessor());

        if ($(element).data("isFirstPass")) {
            $(element).removeData("isFirstPass")
        }
        else {
            // Do something cool
        }
    }
};