任何viewmodel dom更新的Knockout JS事件

时间:2012-02-08 00:52:04

标签: javascript events knockout.js

每当通过Knockout.JS更新DOM时,我都需要运行一个jquery ui位代码。我意识到这可以使用自定义绑定来完成,但这似乎与特定的视图模型有关,我想全局地这样做,所以每当它发生在它触发的任何viewmodel上时?

让我们说我总是希望在所有带有'needsdate'类的文本框上使用JQuery日期选择器,而不是将其添加到我的每个视图模型中,如果我可以在全局范围内完成它将会很棒。

这可能吗?

2 个答案:

答案 0 :(得分:7)

如果您不打算动态添加/删除元素,那么您可以正常连接它们。但是,如果您正在使用动态内容(例如使用修改了其项目的observableArray),那么您有几个选项:

1-与答案here类似,您可以创建自定义绑定。如果您不想将值绑定到视图模型上的属性,则可以将绑定简化为:

ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor) {
        //initialize datepicker with some optional options
        var options = ko.utils.unwrapObservable(valueAccessor());
        $(element).datepicker(options);

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).datepicker("destroy");
        });
    }
}; 

您可以将它放在以下元素上:

<input data-bind="datepicker: { minDate: new Date() }" />

2-另一种选择是使用afterRender的{​​{1}} functionality(和使用template的{​​{1}})来连接你的日期选择器新内容呈现。

答案 1 :(得分:0)

我创建了一个refreshJQuery()函数,可以一次性应用我所有的强健行为。然后,当我在视图模型中订阅observables以更新我的模型时,我调用此函数。一旦加载页面。

function refreshJQuery() {
    $(".draggable, .droppable, .resizable").each(function () {

        var $element = $(this);

        if ($element.hasClass("draggable") && !$element.data("init-draggable")) {
            $element.data("init-draggable", true).draggable(dragBehavior);
        }
        if ($element.hasClass("droppable") && !$element.data("init-droppable")) {
            $element.data("init-droppable", true).droppable(dropBehavior);
        }
        if ($element.hasClass("resizable") && !$element.data("init-resizable")) {
            $element.data("init-resizable", true).resizable(resizeBehavior);
            $(this).children().fadeTo(2000, 0);
            $element.hover(function () {
                $(this).children().fadeTo(200, 1);
            },
            function () {
                $(this).children().fadeTo(750, 0);
            });
        }
    });
};

然后我按如下方式使用它,虽然我已经确定了另外两个我需要调用此函数的observable:

this.updateTime = function () {
    service.updateBookingTimes(this.id(), this.startDate(), this.endDate());
    refreshJQuery();
};

this.startDate.subscribe(this.updateTime, this);
this.endDate.subscribe(this.updateTime, this);

我还实现了@ RPNiemeyer的字段级JQuery订阅解决方案,所以除了他的日期选择器样本之外,我有类似的代码,它将$.button()重新应用于<a>标签,另一个转换为复选框进入iPhone风格的开关。