Maintenant que la différence de performance entre $broadcast
et $emit
a été éliminée, existe-t-il une raison de préférer $scope.$emit
à $rootScope.$broadcast
?
Ils sont différents, oui.
$emit
est limité à la hiérarchie de la portée (vers le haut) - cela peut être bon, si cela correspond à votre conception, mais cela me semble une restriction plutôt arbitraire.
$rootScope.$broadcast
fonctionne dans tout ce qui choisit pour écouter l'événement, ce qui est une restriction plus sensible dans mon esprit.
Est-ce que je manque quelque chose?
EDIT:
Pour clarifier en réponse à une réponse, la direction de la dépêche n'est pas la question que je suis après. $scope.$emit
distribue l'événement vers le haut et $scope.$broadcast
- vers le bas. Mais pourquoi ne pas toujours utiliser $rootScope.$broadcast
pour atteindre tous les auditeurs prévus?
tl; dr (ce tl; dr provient de la réponse de @ sp00m ci-dessous)
$emit
distribue un événement vers le haut ...$broadcast
distribue un événement vers le bas
Explication détaillée
$rootScope.$emit
ne permet qu'aux autres $rootScope
de l'écouter. C'est bien quand vous ne voulez pas que chaque $scope
l'obtienne. Principalement une communication de haut niveau. Pensez-y comme si des adultes se parlaient dans une pièce pour que les enfants ne puissent pas les entendre.
$rootScope.$broadcast
est une méthode qui permet à presque tout de l'entendre. Ce serait l'équivalent de parents qui criaient que le dîner était prêt pour que tout le monde à la maison l'entende.
$scope.$emit
est le moment où vous voulez que $scope
et tous ses parents et $rootScope
entendent l'événement. C’est un enfant qui gémit chez ses parents à la maison (mais pas dans une épicerie où d’autres enfants peuvent entendre).
$scope.$broadcast
est pour le $scope
lui-même et ses enfants. C'est un enfant qui chuchote à ses animaux empaillés pour que leurs parents ne puissent pas entendre.
Ils ne font pas le même travail: $emit
envoie un événement vers le haut dans la hiérarchie des étendues, tandis que $broadcast
distribue un événement vers le bas vers tous les portées enfants. .
J'ai créé le graphique suivant à partir du lien suivant: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
Comme vous pouvez le constater, $rootScope.$broadcast
frappe beaucoup plus d'auditeurs que $scope.$emit
.
De plus, l'effet bouillonnant de $scope.$emit
peut être annulé, alors que $rootScope.$broadcast
ne le peut pas.
$ scope. $ emit: cette méthode distribue l'événement vers le haut (d'enfant à parent)
$ scope. $ broadcast: La méthode envoie l'événement de bas en haut (de parent à enfant) à tous les contrôleurs enfants.
$ scope. $ on: La méthode s’enregistre pour écouter un événement. Tous les contrôleurs qui écoutent cet événement reçoivent une notification de la diffusion ou émettent en fonction de l'emplacement de ceux-ci dans la hiérarchie parent-enfant.
L'événement $ emit peut être annulé par l'un des membres de $ scope qui écoute l'événement.
Le $ on fournit la méthode "stopPropagation". En appelant cette méthode, l’événement peut être empêché de se propager davantage.
Plunker: https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/
En cas de portées frères (les portées qui ne sont pas dans la hiérarchie parent-enfant directe), alors $ emit et $ broadcast ne communiqueront pas avec les portées frères.
Pour plus de détails, veuillez vous référer à http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html
@ Eddie a donné une réponse parfaite à la question posée. Mais je voudrais attirer l'attention sur l'utilisation d'une approche plus efficace de Pub/Sub.
Comme this la réponse suggère,
L'approche $ broadcast/$ on n'est pas très efficace car elle diffuse vers tous les portées (dans une direction ou dans les deux sens de la hiérarchie de la portée). Bien que l'approche Pub/Sub soit beaucoup plus directe. Seuls les abonnés reçoivent les événements. Par conséquent, il ne faut pas que tous les systèmes du système fonctionnent.
vous pouvez utiliser le module angular-PubSub
angular. une fois que vous ajoutez le module PubSub
à la dépendance de votre application, vous pouvez utiliser le service PubSub
pour souscrire et désabonner des événements/sujets.
Facile de s'inscrire:
_// Subscribe to event
var sub = PubSub.subscribe('event-name', function(topic, data){
});
_
Facile à publier
_PubSub.publish('event-name', {
prop1: value1,
prop2: value2
});
_
Pour vous désabonner, utilisez PubSub.unsubscribe(sub);
OR PubSub.unsubscribe('event-name');
.
NOTE N'oubliez pas de vous désabonner pour éviter les fuites de mémoire.
Qu'en est-il dans une situation où vous avez un service en attente, par exemple? Comment puis-je appliquer les modifications à ce service et aux autres composants aléatoires de la page être au courant de ces modifications? Lutte contre ce problème récemment
Construire un service avec RxJS Extensions for Angular .
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx) {
var subject = new rx.Subject();
var data = "Initial";
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
Ensuite, abonnez-vous simplement aux modifications.
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
Les clients peuvent souscrire aux modifications avec DataService.subscribe
et les producteurs aux modifications avec DataService.set
.
Le DEMO sur PLNKR .