【问题标题】:Does jquery remove function also removes knockout bindings?jquery remove 函数是否也会删除淘汰赛绑定?
【发布时间】:2013-12-27 05:58:03
【问题描述】:

我有一个使用淘汰赛绑定的 div。例如,

<div id='my_div'>
  <span data-bind="text: dialog_body"></span> 
</div>

所以,淘汰赛绑定是:

var viewmodel=function(){
 this.dialog_body = 'Some text';
};
ko.applyBindings(new viewmodel(),$("#my_div")[0]);

现在的问题是:如果我打电话给$('#my_div').remove();,这是否也会删除淘汰赛绑定,还是我应该担心内存泄漏?

【问题讨论】:

  • jQuery 不知道 KO,KO 也不关心 jQuery。请参阅cleanNode as discussed herehere。但是,如果您将 DOM 构造为从可观察对象上的 KO 绑定(if/foreach/template/views-in-Durandal)修改,那么所有内容都应该自动清理。
  • 谢谢,我无法让 cleanNode 工作。 html 和 viewmodel 都是由 jquery-ui 动态生成的。因此,我尝试在绑定之前清理节点,但如果还没有绑定,则会引发错误。

标签: javascript jquery html knockout.js


【解决方案1】:

您不需要从 DOM 中删除 span。只需修改您的 KO 跨度以包含可观察布尔值的“可见”绑定。然后,当您想“隐藏”您的跨度时,只需将布尔值设置为 false。

<span data-bind="text: dialog_body, visible: show_span"></span>

然后在您的 KO 代码中,使您的布尔值可观察:

var viewModel = { 
    show_span: ko.observable(true);
}

当你准备好隐藏跨度时:

viewModel.show_span(false);

【讨论】:

  • 我的问题比我给出的例子更复杂。我正在尝试在 jquery-ui 对话框上绑定敲除模板。
【解决方案2】:

jQuery 与 Knockout 无关。它可以删除节点——但这不会清理任何绑定的 KO observables。在给定的情况下,这将意味着存在 轻微 内存泄漏,因为在使用 jQuery 简单地删除节点后,KO 通过内部集合(请参阅ko.utils.domData)维护数据。

在 KO 中用于自行清理的两种传统方法是 cleanNoderemoveNode(但两者都不会删除绑定事件!)应该根据需要使用.. 使用 cleanNode(在通过 KO 绑定的节点上)是最少需要清理数据。


不过,我觉得这里不适合手动清理KO!如果使用正确,标准绑定将已经处理清理。

改为编写如下代码。 (请参阅 Creating custom bindings that control descendant bindings 获取 withProperties;您还必须 make it virtual-element compatible 使用它,如下所示。)

<div id='my_div'>
  <!--ko 'if': someObservable-->
    <!--ko withProperties: { data: someObservable() }-->
      <span data-bind="text: data.dialog_body"></span> 
    <!--/ko-->
  <!--/ko-->
</div>

然后简单地将 observable 设置为创建节点的东西..

someObservable(myVm)

.. 或 undefined 清除它..

someObservable(undefined)

毕竟,一个人通常不会真的是$('#my_div').remove(),而是$('#my_div').dialog('close')。实际上删除节点也可以,只要稍后为新对话框添加 same 元素。

someObservable 值可能来自“根”视图模型 - 我建议使用根视图模型! - 或者它可能来自一个窗口属性,对于那些感觉很老套的人:

window.someObservable = ko.observable()

【讨论】:

  • 拥有一个全局 observable 对我来说不是一个选择,因为我在一个非常大的项目中工作,而全局变量可能会搞砸事情。但是,如果我可以从 id 获取当前绑定,那么我可以更改该绑定上的 observable。也许,ko.dataForko.contextFor 会有所帮助。
  • @faisal 听起来这个大项目需要一些爱!而且我会仍然推荐上述方法 - 但要使包含模型的可观察部分。你看过使用Durandal 吗?它可以轻松地将模型应用于不同的“视图”。 (虽然它支持 SPA,但它不需要用作 SPA。)
  • 好的,我去看看 Durandal。谢谢。我会尝试一下,然后告诉你。
  • @faisal 使用cleanNode 可以正常工作,但是,请确保仅在绑定节点上使用它。您可以使用ko.contextFor 进行检查(它应该为未绑定的节点返回未定义的).. 或者如果它在非绑定节点上使用,则只是尝试/捕获异常。确保分别移除 DOM 事件
  • 我看到了你的编辑。 my_div原本不是页面的一部分,后来被jquery-ui dialog添加了,在添加的时候,它的内容是从外部敲除模板加载的,然后绑定的。
猜你喜欢
  • 2016-03-15
  • 2013-05-04
  • 2013-02-04
  • 1970-01-01
  • 2013-10-31
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
相关资源
最近更新 更多