N'y a-t-il pas d'équivalent $scope.emit()
ou $scope.broadcast()
en angulaire?
Je connais la EventEmitter
fonctionnalité, mais pour autant que je sache , cela ne fera qu'émettre un événement vers l'élément HTML parent.
Et si j'ai besoin de communiquer entre fx. frères et sœurs ou entre un composant à la racine du DOM et un élément imbriqué plusieurs niveaux en profondeur?
Réponses:
Il n'y a pas d'équivalent à
$scope.emit()
ou$scope.broadcast()
de AngularJS. EventEmitter à l'intérieur d'un composant se rapproche, mais comme vous l'avez mentionné, il n'émettra qu'un événement au composant parent immédiat.Dans Angular, il existe d'autres alternatives que je vais essayer d'expliquer ci-dessous.
Les liaisons @Input () permettent au modèle d'application d'être connecté dans un graphe d'objets dirigé (de la racine aux feuilles). Le comportement par défaut de la stratégie de détection des modifications d'un composant consiste à propager toutes les modifications apportées à un modèle d'application pour toutes les liaisons à partir de n'importe quel composant connecté.
À part: Il existe deux types de modèles: Afficher les modèles et Modèles d'application. Un modèle d'application est connecté via des liaisons @Input (). Un modèle de vue est juste une propriété de composant (non décorée avec @Input ()) qui est liée dans le modèle du composant.
Pour répondre à tes questions:
Que faire si j'ai besoin de communiquer entre des composants frères?
Modèle d'application partagé : les frères et sœurs peuvent communiquer via un modèle d'application partagé (tout comme angular 1). Par exemple, lorsqu'un frère modifie un modèle, l'autre frère qui a des liaisons avec le même modèle est automatiquement mis à jour.
Événements de composant : les composants enfants peuvent émettre un événement vers le composant parent à l'aide des liaisons @Output (). Le composant parent peut gérer l'événement et manipuler le modèle d'application ou son propre modèle de vue. Les modifications apportées au modèle d'application sont automatiquement propagées à tous les composants qui se lient directement ou indirectement au même modèle.
Événements de service : les composants peuvent s'abonner aux événements de service. Par exemple, deux composants frères peuvent s'abonner au même événement de service et répondre en modifiant leurs modèles respectifs. Plus d'informations ci-dessous.
Comment puis-je communiquer entre un composant racine et un composant imbriqué à plusieurs niveaux?
$scope.broadcast()
de Angular 1. La section suivante décrit cette idée plus en détail.Exemple d'un service observable qui utilise des événements de service pour propager les modifications
Voici un exemple de service observable qui utilise des événements de service pour propager les modifications. Lorsqu'un TodoItem est ajouté, le service émet un événement notifiant ses abonnés aux composants.
Voici comment un composant racine souscrirait à l'événement:
Un composant enfant imbriqué à plusieurs niveaux souscrirait à l'événement de la même manière:
Voici le composant qui appelle le service pour déclencher l'événement (il peut résider n'importe où dans l'arborescence des composants):
Référence: Change Detection in Angular
la source
itemAdded$
. Est-ce une convention RxJS ou quelque chose? D'où est-ce que ça vient?street
propriété du modèle d'application, mais comme Angular 2 implémente la détection des modifications par identité / référence, aucune modification n'est propagée (onChanges
n'est pas appelée), car la référence du modèle d'application n'a pas changé ( cont ...)Le code suivant comme exemple de remplacement de $ scope.emit () ou $ scope.broadcast () dans Angular 2 à l'aide d'un service partagé pour gérer les événements.
Exemple d'utilisation:
Diffuser:
Auditeur:
Il peut prendre en charge plusieurs arguments:
la source
off(name, listener) { this.listeners[name] = this.listeners[name].filter(x => x != listener); }
J'utilise un service de messagerie qui encapsule un rxjs
Subject
(TypeScript)Exemple Plunker: Message Service
Les composants peuvent s'abonner et diffuser des événements (expéditeur):
(destinataire)
La
subscribe
méthode deMessageService
retourne unSubscription
objet rxjs , qui peut être désabonné comme ceci:Voir également cette réponse: https://stackoverflow.com/a/36782616/1861779
Exemple Plunker: Message Service
la source
Property 'filter' does not exist on type 'Subject<EventMessage>'.
this.handler.pipe(filter(...))
. Voir les opérateurs louables .return this.handler.pipe( filter(message => message.type === type), map(message => message.payload) ).subscribe(callback);
N'UTILISEZ PAS EventEmitter pour votre communication de service.
Vous devez utiliser l'un des types observables. J'aime personnellement BehaviorSubject.
Exemple simple:
Vous pouvez passer l'état initial, ici je passe nul
Lorsque vous souhaitez mettre à jour le sujet
Observez depuis n'importe quel service ou composant et agissez lorsqu'il reçoit de nouvelles mises à jour.
Voici plus d'informations. .
la source
Vous pouvez utiliser
EventEmitter ouobservables pour créer un service Eventbus que vous enregistrez auprès de DI. Chaque composant qui souhaite participer demande simplement le service comme paramètre constructeur et émet et / ou s'abonne aux événements.Voir également
la source
Ma façon préférée de faire est d'utiliser le sujet du comportement ou l'émetteur d'événement (presque le même) dans mon service pour contrôler tous mes sous-composants.
À l'aide de angular cli, exécutez ng gs pour créer un nouveau service, puis utilisez un BehaviorSubject ou EventEmitter
Lorsque vous effectuez cette opération, chaque composant utilisant votre service en tant que fournisseur sera informé du changement. Abonnez-vous simplement au résultat comme vous le faites avec eventEmitter;)
la source
J'ai créé un échantillon pub-sub ici:
http://www.syntaxsuccess.com/viewarticle/pub-sub-in-angular-2.0
L'idée est d'utiliser des sujets RxJ pour câbler un observateur et des observables comme solution générique pour émettre et s'abonner à des événements personnalisés. Dans mon exemple, j'utilise un objet client à des fins de démonstration
Voici également une démonstration en direct: http://www.syntaxsuccess.com/angular-2-samples/#/demo/pub-sub
la source
Voici ma version:
utilisation:
}
émettre:
la source
Nous avons implémenté une directive observable ngModelChange qui envoie toutes les modifications de modèle via un émetteur d'événements que vous instanciez dans votre propre composant. Vous devez simplement lier votre émetteur d'événements à la directive.
Voir: https://github.com/atomicbits/angular2-modelchangeobservable
En html, liez votre émetteur d'événement (countryChanged dans cet exemple):
Dans votre composant tapuscrit, effectuez quelques opérations asynchrones sur EventEmitter:
la source
Événements de service: les composants peuvent s'abonner aux événements de service. Par exemple, deux composants frères peuvent s'abonner au même événement de service et répondre en modifiant leurs modèles respectifs. Plus d'informations ci-dessous.
Mais assurez-vous de vous désabonner à la destruction du composant parent.
la source