program story

AngularJS에서 루트 스코프에 브로드 캐스트 이벤트를 등록 해제하려면 어떻게해야합니까?

inputbox 2020. 11. 19. 08:09
반응형

AngularJS에서 루트 스코프에 브로드 캐스트 이벤트를 등록 해제하려면 어떻게해야합니까?


다음이 있습니다.

angular.module('test')
    .controller('QuestionsStatusController1',
    ['$rootScope', '$scope', '$resource', '$state',
    function ($rootScope, $scope, $resource, $state) {

        $scope.action2 = function() {
            $rootScope.$broadcast('action2@QuestionStatusController1');
        }

    }]);

angular.module('test')
   .controller('QuestionsStatusController2',
   ['$rootScope', '$scope', '$resource', '$state',
   function ($rootScope, $scope, $resource, $state) {

    $rootScope.$on('action2@QuestionStatusController1', function {
         //write your listener here
    })

   }]);

리스닝 이벤트 등록을 취소해야한다는 것을 이해합니다. 누군가 내가 어떻게 코딩 / 할 수 있는지 말해 줄 수 있습니까?


이벤트 등록을 취소하지 않으면 전달한 함수 $on가 정리되지 않기 때문에 메모리 누수가 발생 합니다 (참조가 여전히 존재하므로). 더 중요한 것은 함수가 해당 범위에서 참조하는 모든 변수도 유출된다는 것입니다. 이로 인해 컨트롤러가 응용 프로그램에서 여러 번 생성 / 파괴되는 경우 함수가 여러 번 호출됩니다. 다행히 AngularJS는 메모리 누수 및 원치 않는 동작을 방지하는 몇 가지 유용한 방법을 제공합니다.

  • $on메서드는 이벤트 리스너 등록을 취소하기 위해 호출 할 수있는 함수를 반환합니다. 나중에 사용하기 위해 등록 취소 기능을 변수로 저장해야 var cleanUpFunc = $scope.$on('yourevent', ...);합니다 $on. http://docs.angularjs.org/api/ng.$rootScope.Scope#$on에 대한 설명서를 참조하십시오.

  • 범위가 Angular에서 정리 될 때마다 (즉, 컨트롤러가 파괴됨) $destroy해당 범위에서 이벤트가 발생합니다. $scope$destroy이벤트에 등록하고 cleanUpFunc그에서 전화를 걸 수 있습니다.

이 두 가지 유용한 정보를 함께 연결하여 구독을 올바르게 정리할 수 있습니다. http://plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview에 대한 예를 작성했습니다 . 라인을 주석 처리 cleanUpFunc();한 다음 토글을 누르고 작업 버튼을 몇 번 누르면 이벤트 핸들러가 여러 번 호출되는 것을 알 수 있습니다. 이는 실제로 바람직하지 않습니다.

이제 모든 작업이 끝나면 특정 상황이 올바르게 작동하도록 코드를 QuestionsStatusController2다음과 같이 변경하십시오 .

angular.module('test')
   .controller('QuestionsStatusController2',
   ['$rootScope', '$scope', '$resource', '$state',
   function ($rootScope, $scope, $resource, $state) {

    var cleanUpFunc = $rootScope.$on('action2@QuestionStatusController1', function {
         //write your listener here
    });

    $scope.$on('$destroy', function() {
        cleanUpFunc();
    });

   }]);

호출하여 cleanUpFunc()$destroy의에 대한 이벤트 리스너 action2@QuestionStatusController1이벤트는 취소 구독 할 수 없으며 컨트롤러가 정리됩니다 때 더 이상 메모리가 누수 될 것이다.


Register the listener on the local $scope, not the $rootScope, and the listener will be destroyed automatically when the controller is removed.

So to publish

// EXAMPLE PUBLISHER
angular.module('test').controller('CtrlPublish', ['$rootScope', '$scope',
function ($rootScope, $scope) {

  $rootScope.$broadcast('topic', 'message');

}]);

And subscribe

// EXAMPLE SUBSCRIBER
angular.module('test').controller('ctrlSubscribe', ['$scope',
function ($scope) {

  $scope.$on('topic', function (event, arg) { 
    $scope.receiver = 'got your ' + arg;
  });

}]);

Plunker


Here is the source code about the deregistration logic. You can do:

$rootScope.$on('action2@QuestionStatusController1', function () {
    $rootScope.$$listeners['action2@QuestionStatusController1'] = [];
})

or call the deregistration function returned from $on()

var deregistration = $rootScope.$on('action2@QuestionStatusController1', function () {
    deregistration();
})

$scope.$on('saveCancelLeadInfo', function (event, args) {

        if ($scope.$$listenerCount["saveCancelLeadInfo"] > 1) {

            $scope.$$listenerCount["saveCancelLeadInfo"] = 0;

        } });

참고URL : https://stackoverflow.com/questions/18856341/how-can-i-unregister-a-broadcast-event-to-rootscope-in-angularjs

반응형