"如果"和#34;与"绑定处理程序导致所有事件处理程序丢失(即使使用jQuery' s on()创建)

时间:2015-06-24 22:21:36

标签: javascript jquery knockout.js javascript-events

我使用KnockoutJS,我注意到绑定问题,我可以用这个例子来解释:

<label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label>
<div data-bind="if: displayMessage">Here is a message.<span id="super">SUPER</span> Astonishing.</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
$(function(){
    ko.applyBindings({
        displayMessage: ko.observable(true)
    });

    $('#super').on("click", function(){
        alert('SUUUUUPER');
    });
});

当您第一次点击&#34; SUPER&#34;警报显示的span元素。但是,如果通过将模型的属性displayMessage设置为false并将其放回true以再次显示它来删除块,则对click事件的绑定将不再起作用。

ififnotwith bindingHandlers的源代码我知道knockout删除了DOM克隆并在第一次保存它并使用虚拟元素API重新附加它

所以我的问题是:知道jQuery on()实用程序会将事件处理程序附加到所选元素,即使它们尚不存在。使用导致点击绑定的虚拟元素是否会丢失。如果没有:向我解释会发生什么。

1 个答案:

答案 0 :(得分:1)

我不会在使用KO控制标记的元素上使用id。问题是:Knockout将克隆元素,重构DOM等,最终可能会出现多个具有相同id的元素,这些元素无效,并且基于ID的浏览器行为无法预测。

此外,因为使用if绑定,KO将动态删除/添加DOM节点,您需要this advice以确保jQuery on函数也处理新创建的元素

这是使用class而不是id的其他版本,它可以按预期工作:

$(function(){
    ko.applyBindings({
        displayMessage: ko.observable(true)
    });

    $(document.body).on("click", ".super", function(){
        alert('SUUUUUPER');
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>

<label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label>
<div data-bind="if: displayMessage">Here is a message.<span class="super">SUPER</span> Astonishing.</div>

请注意:

  • 您也可以使用visible绑定,可能无需提及on - 建议。
  • 您应该尝试阻止使用jQuery进行事件处理,并使用Knockout的MVVM样式事件处理(使用click绑定)。