Maison >interface Web >js tutoriel >Comment implémenter la communication entre composants parent-enfant dans Angular2

Comment implémenter la communication entre composants parent-enfant dans Angular2

亚连
亚连original
2018-06-09 10:37:102007parcourir

Cet article présente principalement des exemples de la méthode de communication des composants parent-enfant Angular2. Maintenant, je le partage avec vous et le donne comme référence.

La documentation officielle d'Angular2 contient une introduction détaillée à l'interaction des composants-->Documentation--Interaction entre les composants. Selon le document, il existe 4 façons d'interagir entre les composants, notamment :

  1. Transférer des données du composant parent au composant enfant via la liaison d'entrée (@Input decoration Expose an EventEmitter) ; propriété (@Output decoration) et utilisez cette propriété pour émettre des événements vers le composant parent lorsqu'un événement se produit.

  2. Les composants parents interagissent avec les composants enfants via des variables locales. (# var)

  3. Le composant parent appelle @ViewChild.

  4. Les composants parents et les composants enfants communiquent via des services.

Ici, je vais seulement résumer et présenter en détail 3 méthodes que j'ai utilisées dans le projet. Après avoir lu cet article, vous pourrez probablement obtenir les résultats suivants :

Créez un projet avec la structure de projet suivante :

Communiquez entre les composants parent et enfant via les décorateurs @Input et @Output

@Input : Cette liaison de propriété est utilisée par le composant parent pour transmettre des données au composant enfant. Les composants enfants peuvent intercepter les modifications de propriété via les deux méthodes suivantes :

  1. Utilisez un paramètre de propriété d'entrée pour intercepter les modifications de valeur dans le composant parent.

  2. Utilisez ngOnchanges() pour intercepter les modifications dans les valeurs des attributs d'entrée.

@Output : Cette liaison de données est utilisée par les composants enfants pour transmettre des données et des événements aux composants parents.

<!--parent.component.html-->
<p style="width: 1000px;margin: auto">
<p class="card" style="width: 500px;float: left">
 <p class="card-header">
  父组件
 </p>
 <p class="card-body">
  <h5 class="card-title">父组件</h5>
  <p class="form-group">
   <label for="input">父组件输入:</label>
   <input type="text"
       class="form-control"
       id="input"
       placeholder="Input something"
       [(ngModel)]="parentPrint" 
   >
   <label for="output">父组件输出:</label>
   <input type="text"
       class="form-control"
       id="output"
       placeholder="Output something"
       [(ngModel)]="contentFromChild"
   >
  </p>
 </p>
</p>
<app-child
 [fromParent]="parentPrint"
 (fromChild)="fromChild($event)"
></app-child>
</p>
<!--child.component.html-->
<p class="card" style="width: 500px;">
 <p class="card-header">
  子组件
 </p>
 <p class="card-body">
  <h5 class="card-title">子组件</h5>
  <p class="form-group">
   <label for="input">子组件输入:</label>
   <input type="text"
       class="form-control"
       id="input"
       placeholder="Input something"
       [(ngModel)]="contentFromChild"
   >
   <label for="output">子组件输出:</label>
   <input type="text"
       class="form-control"
       id="output"
       placeholder="Output something"
       [(ngModel)]="fromParent"
   >
  </p>
  <button class="btn btn-primary" (click)="clickChild()">Output方式</button>
 </p>
</p>

L'effet est le suivant : (1. Entrée du composant parent, le composant enfant peut sortir de manière synchrone ; 2. L'entrée du composant enfant nécessite (3.) Cliquez sur le bouton pour déclencher l'événement de lancement et transmettre les données au composant parent )

@Input : pendant la saisie du composant parent, le composant enfant peut simultanément obtenir des données à afficher. Le code de base est le suivant :

//父组件
parentPrint: any;      //ts中,声明一个变量
[(ngModel)]="parentPrint"  //html中,绑定变量,获取用户输入
//html中,将数据传给子组件
<app-child [fromParent]="parentPrint"></app-child> 
//子组件
@Input() fromParent;    //ts中,用于直接接收从父组件获取的数据
[(ngModel)]="fromParent"  //html中,用于显示数据

Utilisez le setter pour intercepter les modifications des valeurs des attributs d'entrée et déclarez une variable privée dans le composant enfant pour obtenir les données transmises par le composant parent, protégeant ainsi le composant supérieur. couche d’obtenir les informations de la couche inférieure. (Un point simple est de ne pas laisser le composant parent savoir ce que le composant enfant utilise pour recevoir les données transmises.) Le même effet peut être obtenu grâce à cette méthode.

//子组件
 private _fromParent: any;   //私有变量,通过setter获取父组件的数据
@Input()            //通过setter获取父组件的数据
 set fromParent(fromParent: any) {
  this._fromParent = fromParent;
 }
 get fromParent(): any {
  return this._fromParent;
 }

@Output : Lorsque le composant parent reçoit des données du composant enfant, le composant enfant expose une propriété EventEmitter Lorsqu'un événement se produit, le composant enfant utilise cette propriété pour émettre des événements (éjection vers le haut). Le composant parent se lie à cette propriété d'événement et répond lorsque l'événement se produit. Le code principal est le suivant :

//子组件
@Output() fromChild = new EventEmitter<any>(); //暴露一个输出属性

<button class="btn btn-primary" (click)="clickChild()">Output方式</button> 
 //触发发射函数,将数据发送给父组件
 clickChild() {
  console.log(&#39;click child&#39; , this.contentFromChild);
  this.fromChild.emit(this.contentFromChild);
 }
//父组件
[(ngModel)]="contentFromChild" //绑定输出子组件的数据
//使用子组件,绑定事件属性
<app-child
 [fromParent]="parentPrint"
 (fromChild)="fromChild($event)"
></app-child>
//事件处理函数
 fromChild(event) {
  console.log(event);
  this.contentFromChild = event;
 }

Le composant parent obtient les données du composant enfant en appelant @ViewChild()

Si la classe du composant parent doit être lu Lorsque vous modifiez les propriétés et les valeurs d'un sous-composant ou appelez une méthode d'un sous-composant, vous pouvez injecter le sous-composant dans le composant parent en tant que ViewChild. ViewChild, comme son nom l'indique, vous permet de voir les propriétés et méthodes des sous-composants.

<!--parent.component.html-->
<p style="width: 1000px;margin: auto">
<p class="card" style="width: 500px;float: left">
 <p class="card-header">
  父组件
 </p>
 <p class="card-body">
  <h5 class="card-title">父组件</h5>
  <p class="form-group">
   <label for="viewoutput">ViewChild父组件输出:</label>
   <input type="text"
       class="form-control"
       id="viewoutput"
       placeholder="ViewChild父组件输出"
       [(ngModel)]="viewOutput"
   >
  </p>
  <button class="btn btn-primary" (click)="clickView()">ViewChild方式</button>
 </p>
</p>
<app-child></app-child>
</p>
<!--child.component.html-->
<p class="card" style="width: 500px;">
 <p class="card-header">
  子组件
 </p>
 <p class="card-body">
  <h5 class="card-title">子组件</h5>
  <p class="form-group">
   <label for="input">子组件输入:</label>
   <input type="text"
       class="form-control"
       id="input"
       placeholder="Input something"
       [(ngModel)]="contentFromChild"
   >
  </p>
 </p>
</p>

L'effet est le suivant :

Code principal du composant parent :

//ts
@ViewChild(ChildComponent)         // 使用viewChild导入引用
private childComponent: ChildComponent;   // 将子组件注入到私有属性
//获取子组件数据并显示
clickView() {
  //直接获取子组件的属性
  this.viewOutput = this.childComponent.contentFromChild;
 }
//html
[(ngModel)]="viewOutput"
 <button class="btn btn-primary" (click)="clickView()">ViewChild方式</button>

Les composants parents et les composants enfants communiquent via des services

Le composant parent et ses composants enfants partagent le même service et utilisent ce service pour établir une communication bidirectionnelle au sein de la famille.

<!--parent.component.html-->
<p style="width: 1000px;margin: auto">
<p class="card" style="width: 500px;float: left">
 <p class="card-header">
  父组件
 </p>
 <p class="card-body">
  <h5 class="card-title">父组件</h5>
  <p class="form-group">
   <label for="serviceoutput">父组件服务输入:</label>
   <input type="text"
       class="form-control"
       id="serviceoutput"
       placeholder="服务输入"
       [(ngModel)]="serviceInput"
   >
  </p>
  <button class="btn btn-primary" (click)="clickService()">Service方式</button>
 </p>
</p>
<app-child></app-child>
</p>
<!--child.component.html-->
<p class="card" style="width: 500px;">
 <p class="card-header">
  子组件
 </p>
 <p class="card-body">
  <h5 class="card-title">子组件</h5>
  <p class="form-group">
   <label for="serviceoutput">子组件服务输入:</label>
   <input type="text"
       class="form-control"
       id="serviceoutput"
       placeholder="服务输入"
       [(ngModel)]="serviceInput"
   >
  </p>
  <button class="btn btn-primary" (click)="clickService()">Service方式</button>
 </p>
</p>
//服务
//meditor.service.ts
import {Injectable} from &#39;@angular/core&#39;;
import {Subject} from &#39;rxjs/Subject&#39;;
import {Observable} from &#39;rxjs/Observable&#39;;

@Injectable()
export class MeditorService {
 private subject = new Subject<MeditorMsg>();
 constructor() {}
 // 获取订阅者
 public getObservable(): Observable<MeditorMsg> {
  return this.subject.asObservable();
 }
 // 推送信息
 public push(msg: MeditorMsg) {
  this.subject.next(msg);
 }
}
// 中间者信息
export interface MeditorMsg {
 id: string;
 body: any;
}

L'effet est le suivant :

Le code de base du composant parent-enfant est similaire, injectez le instance de service dans le constructeur. Les composants parent et enfant eux-mêmes ont un identifiant unique. Que le composant parent ou le composant enfant appelle la méthode push() pour pousser les données, les deux parties peuvent recevoir les données. À ce stade, il est nécessaire de déterminer si le composant parent ou le composant enfant utilise les données en fonction de l'ID. Le code de base est le suivant :

subscription: Subscription = null; //初始化一个订阅对象
//子组件构造函数,用于监听数据推送
constructor(
  private meditor: MeditorService
 ) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === &#39;parent&#39;) {   //id为parent,获取父组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 子组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: &#39;parent&#39;, body: this.serviceInput});
 }
//父组件构造函数,用于监听数据推送
constructor(
  private meditor: MeditorService
 ) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === &#39;child&#39;) {    //id为child,获取子组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 父组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: &#39;parent&#39;, body: this.serviceInput});
 }

Ce que j'ai écrit ci-dessus n'est pas parfait, c'est-à-dire avant la fin du cycle de vie, c'est-à-dire dans le cycle onDestroy, l'abonnement doit être annulé.

Ce qui précède est un résumé des interactions de composants que j'ai utilisées récemment. Personnellement, je pense que l'interaction via les services est plus évolutive. Par exemple, notre projet utilise une barre latérale affichée dynamiquement. Cliquer pour afficher la barre latérale à différents moments affichera différentes choses. À ce stade, la barre latérale est utilisée comme composant parent et le composant enfant est transmis au composant parent dans le cadre du message. Le composant parent génère dynamiquement un modèle basé sur le nom du composant enfant et l'affiche dans la barre latérale. . Après avoir dit tant de bêtises, l'image suivante signifie probablement :

Ce qui précède est ce que j'ai compilé pour tout le monde. J'espère qu'il sera utile à tout le monde à l'avenir.

Articles associés :

Fermetures PHP et fonctions anonymes (tutoriel détaillé)

Comment utiliser le sélecteur de liaison à trois niveaux dans l'applet WeChat

Comment utiliser jquery pour obtenir l'effet accordéon

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn