Knockout.js “添加”的元素上的自定义逻辑;如果;与虚拟元素绑定

Knockout.js “添加”的元素上的自定义逻辑;如果;与虚拟元素绑定,knockout.js,knockout-3.0,Knockout.js,Knockout 3.0,我正在使用“if”绑定的无容器控制流语法: <!-- ko if: property --> <div> <button type="button">My Button</button> </div> 这将使按钮以某种方式工作和感觉 但是由于按钮是基于“if”绑定添加的虚拟元素,库不会为按钮添加功能 处理这种情况的最佳方法是什么? 我可以扩展虚拟元素的“if”绑定吗?一种方法是创建自定义绑定,如 ko.bindingHan

我正在使用“if”绑定的无容器控制流语法:

<!-- ko if: property -->
<div>
    <button type="button">My Button</button>
</div>
这将使按钮以某种方式工作和感觉

但是由于
按钮
是基于“if”绑定添加的虚拟元素,库不会为
按钮
添加功能

处理这种情况的最佳方法是什么?
我可以扩展虚拟元素的“if”绑定吗?

一种方法是创建自定义绑定,如

  ko.bindingHandlers.myLibInit = {
      init: function(element, valueAccessor) {
          $("body").initLib();
      }
  };
让你的虚拟元素像

  <!-- ko if: property -->
  <div>
      <button type="button" data-bind="myLibInit:{}">My Button</button>
  </div>
  <!-- /ko -->

我的纽扣

如果可以修改
initLib
代码,最好的方法是使用委派事件,注册事件处理程序时不依赖于页面上现有的元素。这背后的逻辑是事件在DOM树中冒泡,因此可以在页面中固定的容器(例如
body
)中注册处理,然后指定要处理的事件和选择器。因此,如果用户单击该按钮,事件将冒泡到
body
元素,如果它满足过滤器的要求,则会处理该事件。注册处理时元素是否存在并不重要。这是通过使用
$来完成的。on()
,例如:

$('body').on('click', 'input[type=button]' , function() { /* handler */});
要实现过滤器(在本例中选择所有按钮),可以使用
id
,或向元素(按钮)添加
data-
属性,以便对其进行过滤

jQuery文档

如果无法修改库,则可以使用
可见的
绑定,而不是使用
If
绑定。通过这种方式,可以注册处理程序,并且不会丢失它们。注意:我认为不能在虚拟元素上使用visible,但可以使用具有适当样式的元素使其看起来好像不存在一样


注意:一般来说,您应该尽量避免将ko与jQuery混合使用,因为它们使用不同的方法,同时使用它们可能会导致冲突。

您应该初始化
$(“body”).initLib()
初始化
viewModel.property
后。这不会解决我的问题。KO会随时将该按钮添加到HTML中。发生这种情况后,我需要一种调用initLib()的方法。它不能在任何时候被调用,只有当
property
字段为true或有一些值时才会被添加。您建议在初始化viewModel.property后调用initLib()。它将不起作用,因为如果属性为“false”,则KO不会在DOM中添加按钮,因此initLib()此时不会对按钮产生任何影响。当属性变为“true”时,我需要以某种方式再次调用initLib()。谢谢。是的,这也是我考虑过的选择之一。但这并不漂亮。我想知道是否还有其他方法。当绑定
执行时,如果执行
,它将在dom中注入button元素。所以我认为按钮不再是一个虚拟元素了。谢谢。但该库正在做的一个例子是,当鼠标悬停在按钮上时,它可以显示一个漂亮的工具提示(基于“title”属性)。1) 您不能修改库以使用委派事件吗?这是“非结构化javascript”的技术,例如通过引导(通过提供适当的属性)使用。2) 如果您不能执行我推荐的1,那么您不能简单地初始化库并隐藏元素,这样eevnt处理程序就不会丢失吗?您对这些技术有任何疑问或问题吗?
$('body').on('click', 'input[type=button]' , function() { /* handler */});