例如,我有一个我使用的自定义指令:
<my-directive ng-if="showThis"></my-directive>
当rootScope中定义的showThis
变为true或false时,我需要执行一些DOM操作并附加/删除事件处理程序。在工作流程中可能会多次发生。这就是为什么我有一些问题:
我可以处理ng-if
?
我应该在哪里执行此操作:myDirective的内部链接功能或控制器功能?
我是否真的需要每次都杀死并重新附加事件侦听器以避免内存泄漏?或者AngularJS会为我做这件事吗?
每当ng-if
变为真时,是否会调用链接和控制器函数?
答案 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)
。
回答你的问题:
在链接功能中,使用功能签名中提供的$scope
。
Angular会清理它知道的事件监听器 - 使用ng-click/ng-change/ng-whatever
或$watches
调用$scope
附加的任何内容。但是,如果您通过本机javascript绑定事件:是的,您应该清理。但是,该规则有一个主要的例外 - 如果您绑定到销毁指令时被销毁的DOM元素,JS引擎当然会自动为您释放该内存。
正如@Maximus上面所述,每次ng-if
值为真时都会运行这些函数,因为DOM元素已被完全删除/添加。