你是否需要在$ scope $ destroy事件中取消绑定$ scope。$ on?

时间:2017-02-15 10:53:17

标签: javascript angularjs

我有使用$ 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 个答案:

答案 0 :(得分:11)

$rootScope.$on() 将在您的视图中由于E2E绑定而丢失其表示时自动销毁/清除。请注意,$scope.$on();绑定不会发生这种情况。您还可以查看$scope documentation of AngularJS

用几句话回答:

  • $rootScope.$on()将自动销毁。
  • 您需要手动销毁$rootScope.$on()

该文件说:

  

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

如何销毁//bind event var registerScope = $rootScope.$on('someEvent', function(event) { console.log("fired"); }); // clean up $scope.$on('$destroy', registerScope);

的示例
$scope.$on()

plnkr会向您显示$rootScope.$on()$rootScope.$on();的不同行为。

通过切换此plunkr中的视图,控制器将被重新绑定到您的视图。每次切换视图时都会绑定$rootScope.$on()事件,而不会破坏之前视图的事件绑定。以这种方式,$scope.$on()听众将被叠加/相乘。 $scope.$on('event');绑定不会发生这种情况,因为它会通过切换视图而被破坏(在DOM中丢失E2E绑定表示)。

请注意:

  • $scope.$broadcast('event')会收听$rootScope.$broadcast('event')& $rootScope.$on('event');

  • $rootScope.$broadcast('event')只会收听{{1}}

答案 1 :(得分:4)

不,您不需要删除该绑定。当范围被销毁时,它将被删除。但是,如果将事件绑定到$ rootScope,请记住解除绑定!它可以像这样轻松完成:

        var unregister = $rootScope.$on('eventName', function(e) {
            //doSomething
        });


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

答案 2 :(得分:3)

  

范围销毁 - 当不再需要子范围时,它就是   子范围创建者的责任是通过它来销毁它们   范围。$摧毁()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

的更多信息

答案 3 :(得分: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节点被销毁时,浏览器应删除它们。