如何挂钩ng-if更改?

时间:2016-10-05 07:16:22

标签: javascript angularjs

例如,我有一个我使用的自定义指令:

<my-directive ng-if="showThis"></my-directive>

当rootScope中定义的showThis变为true或false时,我需要执行一些DOM操作并附加/删除事件处理程序。在工作流程中可能会多次发生。这就是为什么我有一些问题:

  1. 我可以处理ng-if

  2. 的更改
  3. 我应该在哪里执行此操作:myDirective的内部链接功能或控制器功能?

  4. 我是否真的需要每次都杀死并重新附加事件侦听器以避免内存泄漏?或者AngularJS会为我做这件事吗?

  5. 每当ng-if变为真时,是否会调用链接和控制器函数?

2 个答案:

答案 0 :(得分:4)

我可以处理ng-if的变化吗?
ng-if中的表达式求值为false时,angular会从DOM中删除您的指令,并触发$scope.$destroy事件。

我应该在哪里这样做:内部链接功能或myDirective的控制器功能?
由于您的指令已从DOM中删除,因此控制器无链接功能对您没有任何帮助。

我是否真的需要每次都杀死并重新附加事件侦听器以避免内存泄漏?或者AngularJS会为我做这件事吗?
Angular将删除附加到已销毁范围的所有$watch侦听器。但是,如果您将观察者附加到其他范围,例如$rootScope,则必须手动删除它们。当DOM元素被销毁时,浏览器将删除附加到DOM inside 指令的所有DOM事件侦听器。如果你有任何事件监听器附加到DOM没有被销毁(在你的指令之外),你将不得不手动删除它们。

每当ng-if变为true时,是否会调用链接和控制器函数?

This answer提供了有关销毁指令时该怎么做的更多信息。

答案 1 :(得分:2)

在决定解决方案之前,您需要考虑一个问题:您希望ng-if处理程序在容器控制器中运行,还是在my-directive链接函数中运行。

如果处理程序的范围限定为容器控制器,则只能$scope.$watch('showThis', handler),在容器控制器实例化期间运行。

但是,如果它的范围是指令,那么您可能正在寻找$scope.$on('$destroy', handler)

回答你的问题:

  1. 在链接功能中,使用功能签名中提供的$scope

  2. Angular会清理它知道的事件监听器 - 使用ng-click/ng-change/ng-whatever$watches调用$scope附加的任何内容。但是,如果您通过本机javascript绑定事件:是的,您应该清理。但是,该规则有一个主要的例外 - 如果您绑定到销毁指令时被销毁的DOM元素,JS引擎当然会自动为您释放该内存。

  3. 正如@Maximus上面所述,每次ng-if值为真时都会运行这些函数,因为DOM元素已被完全删除/添加。