J'ai le suivant:
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
})
}]);
Je crois comprendre que je dois désenregistrer l'événement d'écoute. Quelqu'un peut-il me dire comment je pourrais coder/faire ceci?
Si vous ne désenregistrez pas l'événement, vous obtiendrez une fuite de mémoire car la fonction passée à $on
ne sera pas nettoyée (car sa référence existe toujours). Plus important encore, toute variable dont la fonction fait référence à des références sera également divulguée. Ainsi, votre fonction sera appelée plusieurs fois si votre contrôleur est créé/détruit plusieurs fois dans une application. Heureusement, AngularJS fournit plusieurs méthodes utiles pour éviter les fuites de mémoire et les comportements indésirables:
La méthode $on
renvoie une fonction qui peut être appelée pour annuler l'enregistrement de l'écouteur d'événements. Vous souhaitez enregistrer votre fonction de désenregistrement en tant que variable pour une utilisation ultérieure: var cleanUpFunc = $scope.$on('yourevent', ...);
Voir la documentation pour $on
: http://docs.angularjs.org/api/ng.$rootScope.Scope#$on
Chaque fois qu'une étendue est nettoyée dans Angular (c'est-à-dire qu'un contrôleur est détruit), un événement $destroy
est déclenché sur cette étendue. Vous pouvez vous inscrire à l'événement $scope
de $destroy
et appeler votre cleanUpFunc
à partir de celui-ci.
Vous pouvez lier ces deux éléments utiles pour nettoyer correctement vos abonnements. J'ai rassemblé un exemple de ceci: http://plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview . Si vous commentez la ligne cleanUpFunc();
, puis que vous appuyez à plusieurs reprises sur le bouton bascule-écran, vous remarquerez que notre gestionnaire d'événements est appelé plusieurs fois, ce qui n'est pas vraiment souhaitable.
Maintenant, après tout cela, pour que votre situation spécifique se comporte correctement, modifiez votre code dans QuestionsStatusController2
comme suit:
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();
});
}]);
En appelant cleanUpFunc()
dans $destroy
, votre écouteur d'événements pour l'événement action2@QuestionStatusController1
ne sera plus abonné et vous ne perdrez plus de mémoire lorsque votre contrôleur est nettoyé.
Enregistrez l'écouteur sur le $scope
local, et non sur le $rootScope
, et l'écouteur sera automatiquement détruit lorsque le contrôleur sera supprimé.
Donc pour publier
// EXAMPLE PUBLISHER
angular.module('test').controller('CtrlPublish', ['$rootScope', '$scope',
function ($rootScope, $scope) {
$rootScope.$broadcast('topic', 'message');
}]);
Et abonnez-vous
// EXAMPLE SUBSCRIBER
angular.module('test').controller('ctrlSubscribe', ['$scope',
function ($scope) {
$scope.$on('topic', function (event, arg) {
$scope.receiver = 'got your ' + arg;
});
}]);
Voici le code source relatif à la logique de désenregistrement. Tu peux faire:
$rootScope.$on('action2@QuestionStatusController1', function () {
$rootScope.$$listeners['action2@QuestionStatusController1'] = [];
})
ou appelez la fonction de désenregistrement renvoyée par $on()
var deregistration = $rootScope.$on('action2@QuestionStatusController1', function () {
deregistration();
})
$scope.$on('saveCancelLeadInfo', function (event, args) {
if ($scope.$$listenerCount["saveCancelLeadInfo"] > 1) {
$scope.$$listenerCount["saveCancelLeadInfo"] = 0;
} });