你需要在$scope $destroy事件中解除绑定$scope.$on吗?

10

我使用$on绑定了事件指令,当作用域被销毁时,我需要移除绑定吗?还是会自动完成?此外,我是否需要调用$element.off?

return {
    restrict: 'A',
    link: function($scope, $element, $attrs) {
        $element.on('load', function() {
            $element[0].contentWindow.focus();
        });
        $scope.$on('iframe:focus', function() {
            $element[0].contentWindow.focus();
        });
    }
};
4个回答

14

$scope.$on()监听器将在视图中由于E2E绑定而失去其表示时自动销毁/清理。请注意,对于$rootScope.$on()绑定,这种情况不会发生。您还可以查看AngularJS的$scope文档

简要回答:

  • $scope.$on();会被自动销毁。
  • 你需要手动销毁$rootScope.$on()

文档说:

作用域销毁-当不再需要子作用域时,子作用域的创建者有责任通过scope.$destroy()API销毁它们。这样做是为了阻止$digest调用传播到子作用域,并允许垃圾收集器回收子作用域模型使用的内存。

如何销毁$rootScope.$on()的示例:


```javascript // 创建一个 $rootScope.$on() 的监听器 var listener = $rootScope.$on('someEvent', function(event, args) { /* ... */ });
// 给 $rootScope 上添加一个 $destroy 监听器来销毁 $rootScope.$on() $scope.$on('$destroy', listener); ```
// bind event
const registerScope = $rootScope.$on('someEvent', function(event) {
  console.log("fired");
});

// clean up
$scope.$on('$destroy', registerScope);

这个 plnkr 展示了 $scope.$on()$rootScope.$on() 的不同行为。

通过在这个 plunkr 中切换视图,控制器会重新绑定到你的视图上。每当你切换一个视图时,$rootScope.$on(); 事件就会绑定到一个新的视图上,而不会销毁之前视图的事件绑定。这样一来,$rootScope.$on() 监听器就会被堆叠/累加。这种情况不会发生在 $scope.$on() 绑定上,因为它会在切换视图时被销毁(在 DOM 中失去端到端绑定的表示)。


请注意:

  • $scope.$on('event'); 将监听 $scope.$broadcast('event')$rootScope.$broadcast('event')

  • $rootScope.$on('event'); 只会监听 $rootScope.$broadcast('event')


4
不用移除那个绑定。当作用域被销毁时,它会被移除。但是,如果你将事件绑定到$rootScope,请务必记得解除绑定!可以像这样轻松完成:
        var unregister = $rootScope.$on('eventName', function(e) {
            //doSomething
        });


        $scope.$on('$destroy', unregister);

3
作用域销毁 - 当子作用域不再需要时,由子作用域创建者通过`scope.$destroy()`API销毁它们是必要的。这样做是为了阻止$digest调用进入子作用域并允许垃圾回收器回收子作用域模型使用的内存。
在作用域和元素上注册的监听器在销毁时会自动清除,但是如果您在服务、rootScope或未被删除的DOM节点上注册了监听器,则必须自己清理它,否则可能会引入内存泄漏。
当执行`$scope.$destroy()`时,它将删除通过$on$scope上注册的所有监听器。它不会删除DOM元素或任何通过其他方式添加的事件处理程序。
element.on('click', function (event) {
  ...
});

关于 angular.element 的更多信息,请参阅 https://docs.angularjs.org/api/ng/function/angular.element


0
我需要在作用域销毁时删除绑定吗?
通过重新初始化$$listeners,监听器会自动删除。以下是源代码中相关的部分:
  $destroy: function() {
    ...
    // Disable listeners, watchers and apply/digest methods
    this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;
    this.$on = this.$watch = this.$watchGroup = function() { return noop; };
    this.$$listeners = {};
    ^^^^^^^^^^^^^^^^^^^

我需要调用 $element.off 吗?

不需要,当与 $element 相关联的 DOM 节点被销毁时,它们应该会被浏览器自动移除。


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