【问题标题】:"if" and "with" binding handlers causing all event handlers to be lost (even if created with jQuery's on())"if" 和 "with" 绑定处理程序导致所有事件处理程序丢失(即使使用 jQuery 的 on() 创建)
【发布时间】:2015-09-11 08:08:57
【问题描述】:

我正在使用 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');
    });
});

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

从if、ifnot 和with bindingHandlers 的源代码中我知道,knockout 会在第一次删除 DOM 克隆并保存它并使用虚拟元素 API 重新附加它。

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

【问题讨论】:

    标签: javascript jquery knockout.js jquery-events


    【解决方案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-advice。
    • 您应该尽量避免使用 jQuery 进行此类事件处理,并改用 Knockout 的 MVVM 样式的事件处理(使用 click 绑定)。

    【讨论】:

    • 感谢您的回复...在我的个人项目中,我尝试使用敲除来绑定点击,正如您所说,问题是在某些 UI 中我使用外部插件(例如基于 jquery 的 datetimepicker插件)在它们的实现中绑定事件处理程序,不幸的是这些都丢失了。
    • @user3123258 Knockout 中的所有 DOM 操作都应该发生在绑定中。这意味着如果您使用插件,它们应该有自定义绑定处理程序来设置它们。例如,请参阅stackoverflow.com/questions/6612705/…。
    • THHX Roy J ...我不知道...使用 ko 自定义绑定来使用插件 API 是个好主意 ^^
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 2010-10-22
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    相关资源
    最近更新 更多