任何视图模型dom更新的Knockout JS事件

Knockout JS event for any viewmodel dom update

本文关键字:Knockout JS 事件 更新 视图 模型 dom 任何      更新时间:2023-09-26

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

比方说,我总是希望在所有具有类"needsdate"的文本框上都有一个JQuery日期选择器,而不是将其添加到我的每个视图模型中,如果我能在全局范围内做到这一点,那就太好了。

这可能吗?

如果您不打算动态添加/删除元素,那么您可以像往常一样将它们连接起来。然而,如果您正在处理动态内容(例如使用正在修改其项的observableArray),那么您有两个选项:

1-就像这里的答案一样,你可以创建一个自定义绑定。如果您不想将值绑定到视图模型上的属性,那么您可以将绑定简化为以下内容:

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-另一个选项是使用templateafterRender功能(以及使用templateforeach)在呈现新内容后连接日期选择器。

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

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);
            });
        }
    });
};

然后,我按如下方式使用它,尽管我已经确定了另外两个需要从调用此函数的可观测性

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风格的开关。