繁体   English   中英

淘汰赛“与”绑定删除我的 jquery DOM 事件

[英]Knockout "with" binding removes my jquery DOM events

我有几个在 DOM 加载或文档就绪时创建的 jquery dom 事件。 这些大多是应该应用于我的应用程序中所有表单的默认行为。 例子:

$('input:text').focus(function ()
{
    $(this).select();
});

在应用淘汰赛绑定之前,我可以检查我的 dom 元素并且所有事件都在那里:

敲除结合前

但是当我运行 applyBindings 方法将视图模型绑定到我的 DOM 时, “with”绑定会删除所有与淘汰赛无关的事件:

淘汰赛后

我已尝试按照文档此答案中的说明覆盖cleanExternalData 但这并没有帮助,函数被替换了,但是当模板应用于绑定过程时,事件仍然从 DOM 中删除。

根据记录,这不是with函数的专有行为,但所有匿名模板函数也这样做,foreach、if、ifnot。 正如预期的那样,使用template 的行为也相同。 DOM 元素被完全销毁,存储为模板,然后在满足条件时再次添加到我的文档中,但现在没有任何 jquery 事件处理程序。

如何避免淘汰赛从我的 DOM 元素中删除事件?

您可以使用数据绑定来使用 jquery on() 功能来处理事件,而不是将元素绑定到特定节点。 这是我使用的绑定:

define(['knockout'], function (ko) {
ko.bindingHandlers.eventListener = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var params = ko.utils.unwrapObservable(valueAccessor());
        if (!(params instanceof Array)) {
            params = [params];
        }
        params.forEach(function (param) {
            $(element).on(param.event, param.selector, function (event) {
                param.callback(ko.dataFor(this), ko.contextFor(this), event);
            });
        });
    }
}

});

用法:

<div data-bind="eventListener: [
             { event: 'click', selector: '.copyInclusionRule', callback: copyInclusionRule},
             { event: 'click', selector: '.deleteInclusionRule', callback: deleteInclusionRule}]">
 ... other knockout template stuff here ...
</div>

以上将侦听具有指定类的元素上的单击事件,并在 div 的“范围”内的任何内容接收到事件时执行回调。 'event' 参数的值可以是 on() 使用的任何值。

我认为你不能利用 cleanNode 覆盖的原因是你的 dom 被完全破坏和重新创建......至少这是我的理论,如果有办法获得某种内存 ID 的 pre-applyBindings () dom 元素然后在 applyBindings 被调用之后,是那些新节点? 如果它们是新节点,这不是您无法通过清理修复的问题,这些节点已经消失了。

好的,这是我解决我的问题的方法,我希望这可以向不想破坏他们的 DOM 的其他人澄清一些事情。 如果您不希望淘汰赛破坏您的 DOM,那么从 2.2 版开始就可以实现。 因此,在不必要时销毁 DOM 不是预期行为,可以避免。

我之前尝试过Michael Best创建的几个biding,比如他的using binding 将在淘汰赛 3.5 中出现,以及 let 或 withLight (现在变成using )。 没有一个真正奏效。 这些简化的投标将加载初始对象,但不会在此对象属性更改时更新 dom。

但这帮助我弄清楚我做错了什么。 当我想更新我的 observable 对象时,我使用了myViewModel.observableObject(NewObject) ,就像文档告诉我的那样:

要将新值写入 observable,请调用 observable 并将新值作为参数传递。 例如,调用myViewModel.personName('Mary')会将名称值更改为 'Mary'。

但是我没有传递单个属性的值,而是传递了一个具有相同结构(相同属性)的新对象。 这触发了旧对象被销毁(因此,一秒钟)和一个新对象取而代之的淘汰赛,即使所有属性都在那里,它们只是得到了不同的值。 与文档告诉我的不同,它并没有简单地更改 value ,而是更改了整个对象。

为了解决这个问题,而不是那样做,首先,我必须使用已经创建的这个对象来启动我的 viewModel,使用虚拟数据,这使得当调用 applyBindings时,knockout 不会破坏 DOM。 然后,当我希望我的对象更新时,我将 observable 对象的每个属性的值替换为新对象的值。 这并没有破坏对象,并且淘汰赛正确更新了我的绑定。

myViewModel.setSelectedItem = function setSelectedItem (newObject)
{
    for (var prop in myViewModel.myObservableObject())
        myViewModel.myObservableObject()[prop](newObject[prop]);
}

with绑定仍然杀死了我的一些事件(例如,我的一个组件的 angular ng-change),但它保留了所有 jquery 事件(这很棒)。 而且using绑定根本没有杀死我的任何事件(甚至更好)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM