Dans un tel scénario, où plusieurs/unkown objets pourraient être intéressés par les changements, utilisez $rootScope.$broadcast
de l'élément en cours de modification.
Plutôt que de créer votre propre registre des auditeurs (qui doivent être nettoyés sur divers $détruit), vous devez être en mesure d' $broadcast
à partir du service en question.
Vous devez toujours le code de l' $on
des gestionnaires à chaque auditeur, mais le motif est découplée de multiples appels à l' $digest
et évite donc le risque de longue watchers.
De cette façon, aussi, les auditeurs peuvent aller et venir de la DOM et/ou différent de l'enfant étendues sans le service de changement de comportement.
** mise à jour: exemples **
Émissions ferait le plus de sens dans l'onglet "global" des services qui pourraient avoir un impact d'innombrables autres choses dans votre application. Un bon exemple est celui d'un Utilisateur de service où il y a un certain nombre d'événements qui pourraient avoir lieu tel que la connexion, la déconnexion, la mise à jour, ralenti, etc. Je crois que c'est où les émissions ont le plus de sens parce que tout peut écouter un événement, sans même l'injection du service, et il n'a pas besoin d'évaluer toutes les expressions ou mettre en cache les résultats d'inspecter pour des changements. Il vient de feux et oublie (donc, assurez-sûr que c'est un feu-et-oublier de notification, et non pas quelque chose qui nécessite une action)
.factory('UserService', [ '$rootScope', function($rootScope) {
var service = <whatever you do for the object>
service.save = function(data) {
.. validate data and update model ..
// notify listeners and provide the data that changed [optional]
$rootScope.$broadcast('user:updated',data);
}
// alternatively, create a callback function and $broadcast from there if making an ajax call
return service;
}]);
Le service ci-dessus serait de diffuser un message à tous les portée lors de la save() la fonction s'est terminée et que les données soient valides. Sinon, si c'est une de dollars de ressources ou une soumission ajax, déplacer la diffusion d'appels à la fonction de rappel de sorte qu'il se déclenche lorsque le serveur a répondu. Émissions en fonction de ce modèle particulièrement bien parce que chaque auditeur attend simplement la manifestation sans la nécessité de contrôler la portée sur chaque $digest. L'auditeur pourrait ressembler à:
.controller('UserCtrl', [ 'UserService', '$scope', function(UserService, $scope) {
var user = UserService.getUser();
// if you don't want to expose the actual object in your scope you could expose just the values, or derive a value for your purposes
$scope.name = user.firstname + ' ' +user.lastname;
$scope.$on('user:updated', function(event,data) {
// you could inspect the data to see if what you care about changed, or just update your own scope
$scope.name = user.firstname + ' ' + user.lastname;
});
// different event names let you group your code and logic by what happened
$scope.$on('user:logout', function(event,data) {
.. do something differently entirely ..
});
}]);
L'un des avantages de ceci est l'élimination de plusieurs montres. Si vous étiez en combinant les champs ou en découlant, des valeurs comme l'exemple ci-dessus, vous devez regarder à la fois les propriétés firstname et lastname. Regarder le getUser() la fonction ne fonctionne que si l'utilisateur de l'objet a été remplacé sur les mises à jour, il ne serait pas le feu si l'utilisateur de l'objet seulement de ses propriétés de mise à jour. Dans ce cas, vous auriez à faire une profonde regarder et ce qui est de plus en plus intensive.
$broadcast envoie le message de la portée, il est appelé à descendre dans n'importe quel enfant étendues. Donc l'appeler à partir de $rootScope le feu sur chaque portée. Si vous étiez à $diffusé à partir de votre contrôleur du champ d'application, par exemple, il serait de feu que dans les étendues qui héritent de votre contrôleur de portée. $émettent va dans le sens inverse et se comporte de façon similaire à un DOM événement en ce qu'il les bulles du champ d'application de la chaîne.
Gardez à l'esprit qu'il existe des scénarios où $de diffusion fait beaucoup de sens, et il existe des scénarios où $watch est une meilleure option, surtout si dans un isolat portée avec une très montre spécifique de l'expression.