我正在使用 KnockoutJS,我注意到绑定(bind)存在问题,我可以使用此示例进行解释:
<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
以再次显示绑定(bind)来删除该 block 点击事件不再起作用。
从if
、ifnot
和with
绑定(bind)处理程序的源代码中我知道knockout会在第一次删除DOM克隆并保存它并使用虚拟元素 API 重新附加它。
所以我的问题是:知道 jQuery on()
实用程序会将事件处理程序附加到所选元素,即使它们尚不存在。是使用虚拟元素导致点击绑定(bind)丢失。如果没有:向我解释会发生什么。
最佳答案
我不会在具有 KO 控制标记的元素上使用 id
。问题是:Knockout 会克隆元素、重构 DOM 等,最终可能会得到多个具有相同 id 的元素,这是无效的,并且从这一点来看,基于 ID 的浏览器行为是不可预测的。
此外,由于使用 if
绑定(bind),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
绑定(bind),这可能避免需要提到的on
-advice。 - 您应该尽量避免使用 jQuery 进行此类事件处理,而改用 Knockout 的 MVVM 样式事件处理(利用
click
绑定(bind))。
关于javascript - "if"和 "with"绑定(bind)处理程序导致所有事件处理程序丢失(即使是使用 jQuery 的 on() 创建的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31038143/