"已销毁"控制器中的角度$rootScope $on侦听器继续运行



我在index.html中设置了带有ng-view指令的Angular应用程序,其中使用$ RouteProvider配置配置的视图,并且每个视图都有其自己的控制器。在一个视图控制器中,我有一个$ rootscope。听众观看活动的$。我希望当我更改视图时,这个听众不会再运行,但事实并非如此。即使我切换到不再使用该控制器的视图,手表仍将其触发时保持呼叫代码。

我已经设置了一些测试代码来收听$毁灭事件,我可以看到$ destion destion事件正在触发,但侦听器函数仍然运行。我已经打印出$ scope。在手表功能和$ destroy destrot Event Lieser中,$ ID都可以看到IDS匹配。因此,似乎即使在特定范围发生$销毁事件之后,听众的$仍在继续运行。为什么这样?我的印象是,当导航到另一个视图时,或者在任何情况下,控制器被摧毁,然后清除了听众。

plnkr:http://plnkr.co/edit/txssxqjy5pvltaiar4xd?p = preview

var animateApp = angular.module('animateApp', ['ngRoute', 'ngAnimate']);
animateApp.config(function($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'page-home.html',
            controller: 'mainController'
        })
        .when('/about', {
            templateUrl: 'page-about.html',
            controller: 'aboutController'
        })
        .when('/contact', {
            templateUrl: 'page-contact.html',
            controller: 'contactController'
        });
});
angular.module('animateApp').service('service', ['$interval', '$rootScope', service]);
function service ($interval, $rootScope) {
    var service = {};
    service.abc = 1;
        $interval(function() {
        service.abc++;
        $rootScope.$broadcast('service.abc', service.abc);
    }, 500);
    return service;
}

animateApp.controller('mainController', function($scope, $rootScope, service) {
    $scope.pageClass = 'page-home';
    $scope.$on('$destroy', function iVeBeenDismissed() {
                        console.log('goodbye ' + $scope.$id);
      // release resources, cancel request...
    })
    $rootScope.$on('service.abc', function (newval) {
        console.log($scope.$id);
    })
});
animateApp.controller('aboutController', function($scope) {
    $scope.pageClass = 'page-about';
});
animateApp.controller('contactController', function($scope) {
    $scope.pageClass = 'page-contact';
});

,因此问题已经完全改变,因此上下文完全不同,所以我以前的答案不再与问题有关,除了它的适用方式完全相同。

您可以在与下面的答案相同的方面解开听众。

$rootScope.$on()返回一个未注销的功能。

因此,您的mainController可以重新编写为:

animateApp.controller('mainController', function($scope, $rootScope, service) {
    $scope.pageClass = 'page-home';
    var unregister = $rootScope.$on('service.abc', function (newval) {
        console.log($scope.$id);
    });
    $scope.$on('$destroy', unregister);
});

上一个答案

当控制器的范围被销毁时,您应该确保您解开手表。

创建手表时,Angular返回您创建的手表的未连接功能。这里覆盖得很好。

创建对您创建的手表的引用:

var unbinder = $scope.$watch("foo.bar", doStuff);

请注意范围的破坏,但请致电您的unbinder

$scope.$on("$destroy", function(){
    if(typeof unbinder === "function")
        unbinder();
});

调用unbinder功能后,您的手表将被删除。

您应该在控制器中添加$destroy事件侦听器:

    scope.$on('$destroy', function () {
      element.off('blur'); // example
      element = null;
    });

这样,您将手动确保在不活动控制器上不会再有活跃的观察者。

最新更新