J'ai deux composants comme suit et je souhaite appeler une fonction à partir d'un autre composant. Les deux composants sont inclus dans le troisième composant parent using directive.
Composant 1:
@component(
selector:'com1'
)
export class com1{
function1(){...}
}
Composante 2:
@component(
selector:'com2'
)
export class com2{
function2(){...
// i want to call function 1 from com1 here
}
}
J'ai essayé d'utiliser @input
et @output
mais je ne comprends pas exactement comment l'utiliser et comment appeler cette fonction, quelqu'un peut-il m'aider?
angular
angular2-components
noobProgrammer
la source
la source
Réponses:
Si com1 et com2 sont frères, vous pouvez utiliser
com2 émet un événement en utilisant un
EventEmitter
Ici, le composant parent ajoute une liaison d'événement pour écouter les
myEvent
événements, puis appellecom1.function1()
lorsqu'un tel événement se produit.#com1
est une variable de modèle qui permet de faire référence à cet élément ailleurs dans le modèle. Nous l' utilisons pour fairefunction1()
le gestionnaire d'événements pourmyEvent
decom2
:Pour d'autres options de communication entre les composants, voir également interaction avec les composants
la source
<sibling1 (myEvent)="...">
est une liaison d'événement pour le parent / hôte, car c'est le seul moyen fourni par Angular. Le gestionnaire d'événements appelle cependant une méthode sur l'autre frère (com1
). Le parent est utilisé comme médiateur.somecomponent.ts
?Tout d'abord, ce dont vous avez besoin pour comprendre les relations entre les composants. Ensuite, vous pouvez choisir la bonne méthode de communication. Je vais essayer d'expliquer toutes les méthodes que je connais et utilise dans ma pratique pour la communication entre les composants.
Quels types de relations entre les composants peut-il y avoir?
1. Parent> Enfant
Partage de données via l'entrée
C'est probablement la méthode la plus courante de partage de données. Cela fonctionne en utilisant le
@Input()
décorateur pour permettre aux données d'être transmises via le modèle.parent.component.ts
child.component.ts
C'est une méthode très simple. C'est facile a utiliser. Nous pouvons également détecter les modifications apportées aux données dans le composant enfant en utilisant ngOnChanges .
Mais n'oubliez pas que si nous utilisons un objet comme données et modifions les paramètres de cet objet, la référence à celui-ci ne changera pas. Par conséquent, si nous voulons recevoir un objet modifié dans un composant enfant, il doit être immuable.
2. Enfant> Parent
Partage de données via ViewChild
ViewChild permet à un composant d'être injecté dans un autre, donnant au parent l'accès à ses attributs et fonctions. Une mise en garde, cependant, est qu'il
child
ne sera disponible qu'après l'initialisation de la vue. Cela signifie que nous devons implémenter le hook de cycle de vie AfterViewInit pour recevoir les données de l'enfant.parent.component.ts
child.component.ts
Partage de données via Output () et EventEmitter
Une autre façon de partager des données consiste à émettre des données de l'enfant, qui peuvent être répertoriées par le parent. Cette approche est idéale lorsque vous souhaitez partager des modifications de données qui se produisent sur des éléments tels que des clics sur des boutons, des entrées de formulaire et d'autres événements utilisateur.
parent.component.ts
child.component.ts
3. Frères et sœurs
Enfant> Parent> Enfant
J'essaie d'expliquer ci-dessous d'autres moyens de communiquer entre frères et sœurs. Mais vous pouvez déjà comprendre l'une des façons de comprendre les méthodes ci-dessus.
parent.component.ts
child-one.component.ts
child-two.component.ts
4. Composants indépendants
Toutes les méthodes que j'ai décrites ci-dessous peuvent être utilisées pour toutes les options ci-dessus pour la relation entre les composants. Mais chacun a ses propres avantages et inconvénients.
Partage de données avec un service
Lorsque vous passez des données entre des composants qui n'ont pas de connexion directe, tels que des frères et sœurs, des petits-enfants, etc., vous devez utiliser un service partagé. Lorsque vous avez des données qui doivent toujours être synchronisées, je trouve le RxJS BehaviorSubject très utile dans cette situation.
data.service.ts
first.component.ts
second.component.ts
Partage de données avec un itinéraire
Parfois, vous devez non seulement transmettre des données simples entre les composants, mais également enregistrer un état de la page. Par exemple, nous voulons enregistrer un filtre sur le marché en ligne, puis copier ce lien et l'envoyer à un ami. Et nous nous attendons à ce qu'il ouvre la page dans le même état que nous. La première, et probablement la plus rapide, pour ce faire serait d'utiliser des paramètres de requête .
Les paramètres de requête ressemblent davantage à
/people?id=
oùid
peut égaler tout et vous pouvez avoir autant de paramètres que vous le souhaitez. Les paramètres de requête seraient séparés par le caractère esperluette.Lorsque vous travaillez avec des paramètres de requête, vous n'avez pas besoin de les définir dans votre fichier de routes, et ils peuvent être nommés paramètres. Par exemple, prenez le code suivant:
page1.component.ts
Dans la page de réception, vous recevrez ces paramètres de requête comme suit:
page2.component.ts
NgRx
Le dernier moyen, plus compliqué mais plus puissant, est d'utiliser NgRx . Cette bibliothèque n'est pas destinée au partage de données; c'est une puissante bibliothèque de gestion d'état. Je ne peux pas dans un court exemple expliquer comment l'utiliser, mais vous pouvez aller sur le site officiel et lire la documentation à ce sujet.
Pour moi, NgRx Store résout plusieurs problèmes. Par exemple, lorsque vous avez affaire à des observables et lorsque la responsabilité de certaines données observables est partagée entre différents composants, les actions de stockage et le réducteur garantissent que les modifications de données seront toujours effectuées «de la bonne manière».
Il fournit également une solution fiable pour la mise en cache des requêtes HTTP. Vous pourrez stocker les demandes et leurs réponses afin de pouvoir vérifier que la demande que vous faites n'a pas encore de réponse stockée.
Vous pouvez en savoir plus sur NgRx et comprendre si vous en avez besoin dans votre application ou non:
Enfin, je tiens à dire qu'avant de choisir certaines des méthodes de partage de données, vous devez comprendre comment ces données seront utilisées à l'avenir. Je veux dire peut-être que maintenant, vous pouvez utiliser juste un
@Input
décorateur pour partager un nom d'utilisateur et un nom de famille. Ensuite, vous ajouterez un nouveau composant ou un nouveau module (par exemple, un panneau d'administration) qui a besoin de plus d'informations sur l'utilisateur. Cela signifie que cela peut être une meilleure façon d'utiliser un service pour les données utilisateur ou une autre façon de partager des données. Vous devez y réfléchir davantage avant de commencer à mettre en œuvre le partage de données.la source
Vous pouvez accéder à la méthode du composant un à partir du composant deux.
componentOne
composantDeux
componentTwo fichier html
la source
Composant 1 (enfant):
Composant 2 (parent):
la source
@ViewChild
qui a fonctionné pour moi. Merci pour cet exemple.Cela dépend de la relation entre vos composants (parent / enfant) mais la meilleure façon / générique de faire communiquer des composants est d'utiliser un service partagé.
Voir ce document pour plus de détails:
Cela étant dit, vous pouvez utiliser ce qui suit pour fournir une instance de com1 dans com2:
Dans com2, vous pouvez utiliser les éléments suivants:
la source
@Input
le terrain?<button (click)="dbgraph.displayTableGraph()">Graph</button> <dbstats-graph #dbgraph></dbstats-graph>
Notez la variable locale
#dbgraph
sur le composant enfant, que le parent peut utiliser pour accéder à ses méthodes (dbgraph.displayTableGraph()
).la source
En utilisant Dataservice, nous pouvons appeler la fonction à partir d'un autre composant
Component1: Le composant que nous appelons la fonction
dataservice.ts
Component2: le composant qui contient la fonction
la source
if ( this.bookmarkRoot.callToggle.observers.length === 0 ) { this.bookmarkRoot.callToggle.subscribe(( data ) => { this.closeDrawer(); } ) }