【问题标题】:Knockout JS event for any viewmodel dom update任何 viewmodel dom 更新的 Knockout JS 事件
【发布时间】:2012-02-29 11:28:40
【问题描述】:

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

假设我总是希望在所有具有“needsdate”类的文本框上使用 JQuery 日期选择器,而不是将其添加到我的每个视图模型中,如果我能在全球范围内这样做会很棒。

这可能吗?

【问题讨论】:

  • 你能解释一下你的场景吗?通常,您将使用绑定到可观察对象的自定义绑定。当可观察到的变化时,绑定将针对绑定所在的元素运行任何必要的 jQuery UI 代码。有一种方法可以满足您的要求,但我想在提出建议之前了解更多有关该用例的信息,因为这不是正常的方法。
  • 更新了我的主要帖子:假设我总是想要一个 JQuery datepicker 在所有具有类“needsdate”的文本框中,而不是将它添加到我的每个视图模型中,如果我能做到这一点会很棒全球范围内。这有帮助吗?
  • 如果您没有绑定到视图模型,那么您可能不需要为此敲除。
  • 我很确定我有同样的情况,Knockout 在刷新 UI 时删除了 JQuery 句柄,因此要阻止它们踩到对方的脚趾并不容易。常见的建议解决方案是在 mouseover 上使用 $.on() 方法来重新应用行为,但这不适用于例如 droppable (悬停不计算在内,因为您在两者之间拖动元素)。另一种方法是创建一个绑定处理程序,该处理程序在绑定更新时应用 JQuery,但这并不总是适用于模板绑定,例如模板中的任何元素都可能适用于 JQuery

标签: javascript events knockout.js


【解决方案1】:

如果您不打算动态添加/删除元素,那么您可以像往常一样将它们连接起来。但是,如果您正在处理动态内容(例如使用修改其项目的 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- 另一个选项是使用templateafterRender functionality(以及使用templateforeach)在呈现新内容后连接您的日期选择器。

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2013-01-10
      • 2014-09-23
      • 2015-01-17
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 2012-03-29
      • 2018-05-20
      相关资源
      最近更新 更多