Knockout和JQueryUI绑定不会调用更新回调

时间:2015-03-28 11:19:57

标签: jquery-ui knockout.js

使用自定义绑定创建foreach绑定时,"更新:"将新元素推送到视图模型时,不会调用回调。 但是,新的跨度(非手风琴)项目正在创建。

<div data-bind="foreach:items, koAccordion: {}">
<div>
<span data-bind="text: id"></span>
</div>
<div>
<span data-bind="text: name"></span>
</div>
</div>

剧本:

    ko.bindingHandlers.koAccordion = {
         init:function(element, valueAccessor, allBindingsAccessor, viewModel,bindingContext) {
                console.log("INITIALIZATION CALLBACK");
                $(element).accordion();
            },
    update:function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                console.log("UPDATING CALLBACK");
                $(element).accordion('destroy').accordion();
            }
    };
function Item(id,name,description){
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.description = ko.observable(description);
}


var viewModel = {
    items:ko.observableArray([new Item("New Id","New Name","New Description")]),
    addItem:function(id,name,description){
        viewModel.items.push(new Item(id,name,description))
    }    
};


ko.applyBindings(viewModel);

1 个答案:

答案 0 :(得分:0)

绑定的update()函数在其依赖关系发生变化时被调用。

这意味着您必须在update()的正文内触发淘汰赛的依赖关系跟踪。这通常通过生成可观察的基础值(换句话说,通过调用它)来实现。

通常你也会在函数中使用该值,但在这种情况下你只需要这个步骤,因此依赖关系跟踪会注意到有一个订阅者。

这将有效:

<!--                                         pass observable here -->
<div data-bind="foreach: items, koAccordion: items">
    <div>
        <span data-bind="text: id"></span>
    </div>
    <div>
        <span data-bind="text: name"></span>
    </div>
</div>

ko.bindingHandlers.koAccordion = {
    init: function (element, valueAccessor) {
        $(element).accordion();

        // properly destroy the widget when the element gets removed
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).accordion('destroy');
        });
    },
    update: function (element, valueAccessor) {
        // unwrap the observable: this registers an implicit subscription
        ko.unwrap(valueAccessor());
        $(element).accordion('refresh');
    }
};

但实质上,您可以完全跳过update回调,而是使用显式订阅:

ko.bindingHandlers.koAccordion = {
    init: function (element, valueAccessor) {
        var items = valueAccessor(),
            subscription;

        $(element).accordion();

        // set up an explicit subscription
        subscription = items.subscribe(function () {
            $(element).accordion('refresh');
        });

        // properly destroy the widget when the element gets removed
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            subscription.dispose();
            $(element).accordion('destroy');
        });
    }
};

话虽如此,你应该使用一个成熟的jQueryUI自定义绑定库,而不是自己动手:http://gvas.github.io/knockout-jqueryui/