5 votes

$rootScope comme agrégateur d'événements

J'utilise angular-js. J'ai un service qui doit déclencher un événement à chaque fois que quelque chose se produit. Pour ce faire, j'ai besoin d'un objet qui agira en tant que event aggregator .

  1. Dois-je en construire un ? Ou dois-je utiliser le $rootScope ?
  2. Au cas où je devrais utiliser $rootScope Comment puis-je m'assurer qu'il n'y a pas de conflits de noms d'événements ?
  3. Est-il efficace d'utiliser $rootScope pour les événements qui n'en ont pas besoin pour se propager aux scopes enfants ?

13voto

yuxhuang Points 929

J'ai modélisé et implémenté le mécanisme suivant dans un projet web pour tablettes :

  1. Définir notifications dans vos services. Je ne voulais pas utiliser le terme événements car je ne voulais pas qu'il soit confondu avec Événements DOM par les autres développeurs de mon équipe. Et un nom semi-typé pour une notification est plus facile pour l'IDE avec le support intellisense et pour le débogage. Par exemple, j'ai une Device service qui $broadcast(Device.Notification.OrientationDidChange) lorsque l'orientation d'une tablette est modifiée.

  2. Utilisez Scope à des objets $broadcast o $emit notifications en fonction de vos besoins. Par exemple,

    • Pour le monde entier notifications comme le précédent, je le fais : $rootScope.$broadcast(Device.Notification.OrientationDidChange) . Ainsi, tous les auditeurs peuvent écouter sur leur propre portée sans injecter $rootScope .
    • Pour notifications locales qui pourrait éventuellement n'affecter que l'étendue actuelle (et ses enfants), comme un fichier notification qu'un scope doit dire à tous ses scopes enfants que la disposition du contrôleur courant est modifiée, habituellement je le fais : scope.$broadcast(UI.Notification.NeedsLayout)UI est un service prédéfini pour contenir les constantes liées à l'interface utilisateur, et scope est la portée actuelle.
    • Pour certaines notifications qu'un scope enfant doit envoyer vers le haut, par exemple, une directive slider qui indique aux scopes ascendants que l'élément rangeStart a changé (en plus de la liaison bidirectionnelle normale), j'utilise : scope.$emit(Slider.Notification.RangeStartDidChange)scope est la portée actuelle.
  3. Cette approche est un peu verbeuse dans un petit projet. Vous pouvez vous contenter d'utiliser $rootScope.$emit(Notification) tout le temps, et laisser tous les auditeurs faire $rootScope.$on(Notification, callback) pour recevoir ces notifications.

  4. Dans certaines situations, vous pourriez vouloir définir ces notifications dans un service centralisé afin d'éviter plus facilement les conflits de noms. Cela dépend en fait de la convention de nommage de votre projet.

  5. La mise en œuvre (valeurs réelles) de ces notifications peut varier. Je préfère utiliser strings .

  6. Avec $broadcast o $emit vous pouvez également passer des arguments supplémentaires aux écouteurs, par exemple, $broadcast(Notification, arg1, arg2) ... Angulaire Documentation de l'UE est très détaillée.

4voto

g00fy Points 1777

Jetez un coup d'œil à http://docs.angularjs.org/api/ng.$rootScope.Scope#$broadcast .

  1. Utilisation de $rootScope en tant qu'agrégateur d'événements, c'est parfait, à moins que vous ne déclenchiez des événements en dehors du cadre de votre activité. digest cycle ou le déclenchement de plusieurs (100+) événements en même temps où d'autres solutions peuvent être plus appropriées .
  2. Une pratique acceptée serait d'utiliser l'espacement des noms ( namespace:event - utilisé par Backbone.Marionette )
  3. Utilisez $emit sur une portée enfant au lieu de $broadcast sur $rootScope - $emit se propage uniquement vers le haut, où $broadcast se propage vers le bas - vers tous les enfants

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X