你可以使用ko.applyBindings绑定一个局部视图吗?

259
我正在使用KnockoutJS,有一个主视图和视图模型。我想打开一个对话框(jQuery UI对话框),其中包含另一个视图,该视图将绑定到一个单独的子视图模型。
对话框内容的HTML是通过AJAX检索的,因此我希望能够在请求完成后调用ko.applyBindings,并且只想将子视图模型绑定到通过ajax加载到对话框div中的HTML部分。
这样做是否可行,或者我需要在页面最初加载时加载所有视图和视图模型,然后再调用ko.applyBindings
4个回答

432

ko.applyBindings接受第二个参数,用作根元素。

这让你可以像这样做:

<div id="one">
  <input data-bind="value: name" />
</div>

<div id="two">
  <input data-bind="value: name" />
</div>

<script type="text/javascript">
  var viewModelA = {
     name: ko.observable("Bob")
  };

  var viewModelB = {
     name: ko.observable("Ted")
  };

  ko.applyBindings(viewModelA, document.getElementById("one"));
  ko.applyBindings(viewModelB, document.getElementById("two"));
</script>

因此,您可以使用此技术将viewModel绑定到动态加载到对话框中的内容。总体而言,您只需要小心不要在同一元素上多次调用applyBindings,否则将会附加多个事件处理程序。


18
如果您想在未来的某个时间点删除绑定,可以调用 ko.cleanNode(document.getElementById("one") 来清理代码,或者使用 ko.removeNode(document.getElementById("one") 来清理代码并从 DOM 中删除节点。 - Mike B
7
请注意,cleanNoderemoveNode不会移除事件处理程序,因此请谨慎使用。在某些情况下,最好在这些区域使用templatewith绑定,以便渲染新元素。 - RP Niemeyer
7
目前在KO中还缺少这样的功能。我们并不特意要求人们“重新绑定”某些部分。然而,如果引用了jQuery,KO会使用它来附加事件,因此您可以使用 $(element).unbind(); 来删除所有处理程序。 - RP Niemeyer
5
这些函数(applyBindings、cleanNode、removeNode)在哪里有文档?我在 knockoutjs.com 上找不到它们的函数签名。 - EricP
2
希望这个信息在文档中容易被找到。我甚至没有看到提及它的地方。 - Travis Kaufman
显示剩余4条评论

61

尽管Niemeyer的答案更正确回答了这个问题,但是你也可以采用以下方法:

<div>
  <input data-bind="value: VMA.name" />
</div>

<div>
  <input data-bind="value: VMB.name" />
</div>

<script type="text/javascript">
  var viewModels = {
     VMA: {name: ko.observable("Bob")},
     VMB: {name: ko.observable("Ted")}
  };

  ko.applyBindings(viewModels);
</script>

这意味着你不需要指定DOM元素,甚至可以将多个模型绑定到同一个元素上,就像这样:

<div>
  <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>

4
你可以使用 "with" 关键字将页面的区域分配给各个模型 — data-bind="with: VMA" - lexicalscope
3
是的,但是 with 的代价不菲,请参见:链接 - mhu

7
我已成功将自定义模型绑定到运行时元素上。这是代码:http://jsfiddle.net/ZiglioNZ/tzD4T/457/ 有趣的地方在于我将"data-bind"属性应用于我未定义的元素上。
    var handle = slider.slider().find(".ui-slider-handle").first();
    $(handle).attr("data-bind", "tooltip: viewModel.value");
    ko.applyBindings(viewModel.value, $(handle)[0]);

我在使用 ko 2.3 时遇到了问题,上面的代码位于一个自定义处理程序中,当我应用全局 ko.applyBindings() 时会调用该处理程序。现在我收到错误消息“您不能多次向同一元素应用绑定”。我仍在努力弄清楚为什么会出现这个错误。我们不能将绑定多次应用于同一变量,每次应用于不同的元素吗? - ZiglioUK
这是安装了 ko 2.3 版本但无法工作的代码示例:http://jsfiddle.net/ZiglioNZ/tzD4T/458/ - ZiglioUK
在调用 applyBinding 绑定局部视图之前添加调用 ko.cleanNode() 方法似乎没有帮助:http://jsfiddle.net/ZiglioNZ/tzD4T/459/ - ZiglioUK
解决了:我甚至不需要调用applyBindings! - ZiglioUK
我刚刚编辑了 knockoutjs 的源代码,并注释掉了函数 twrows 部分的代码,“您不能多次对同一元素应用绑定”现在一切正常… 我知道这是一个不太干净的解决方案,但我对这个库还不熟悉,所以不知道如何避免在我的问题中多次应用它。 - Geomorillo
@Geomorillo,不确定你的情况,但在我的情况下,我只需要应用属性"data-bind",无需再次调用ok.applyBindings(),即使只是在部分视图上。 - ZiglioUK

0

看起来很复杂。KO 3.0 会更简单吗? - ZiglioUK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接