Maison  >  Article  >  interface Web  >  Méthode de communication des composants parent-enfant Angular2

Méthode de communication des composants parent-enfant Angular2

php中世界最好的语言
php中世界最好的语言original
2018-03-23 09:36:561804parcourir

Cette fois, je vais vous présenter la méthode de communication du composant parent-enfant Angular2. Quelles sont les précautions lors de l'utilisation de la méthode de communication du composant parent-enfant Angular2. Ce qui suit est un cas pratique, jetons un coup d'œil. .

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 : la Data Binding 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('click child' , 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 dans les composants enfants.

<!--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 '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';
@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 des composants parent-enfant est similaire, dans le constructeur Injectez l'instance de service en elle-même et les composants parent et enfant 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 === 'parent') {   //id为parent,获取父组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 子组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: 'parent', body: this.serviceInput});
 }
//父组件构造函数,用于监听数据推送
constructor(
  private meditor: MeditorService
 ) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === 'child') {    //id为child,获取子组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 父组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: 'parent', body: this.serviceInput});
 }

我上面写的还不是很完善,就是在生命周期结束前,也就是在onDestroy周期中,要取消订阅。

以上,就是最近在使用的组件交互的总结。个人觉得通过服务来交互的可扩展性更强。例如,我们项目中用到了一个动态显示的侧栏,不同时期点击显示侧栏要显示不同的东西。这个时候把侧栏作为父组件,子组件作为消息的一部分传递给父组件,父组件根据子组件名动态生成模板,显示在侧栏上面。说了这么多废话大概就是下图的意思:

最后附上demo源码:父子组件交互demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

jQuery代码优化方式的总结

360浏览器兼容模式的页面显示不全怎么处理

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