今回はAngular2の親子コンポーネントの通信方法についてご紹介します。 Angular2の親子コンポーネントの通信方法を使用する際の注意点について、実際に見てみましょう。
Angular2 公式ドキュメントには、コンポーネントの相互作用 ->ドキュメント - コンポーネント間の相互作用について詳しく説明されています。ドキュメントによると、コンポーネント間で対話する方法は 4 つあります。イベントが発生した場合、この属性を使用してイベントを親コンポーネントに送信します。
親コンポーネントと子コンポーネントは、ローカル変数を通じて対話します。 (#var)
親コンポーネントは @ViewChild を呼び出します。
親コンポーネントと子コンポーネントはサービスを通じて通信します。
私がプロジェクトで使用した3つの方法だけを要約して詳しく紹介します。この記事を読んだ後、おそらく次の結果を達成できるでしょう:
@Input および @Output デコレーターを介して親コンポーネントと子コンポーネントの間で通信します
@Input: この属性バインディングは、データを子コンポーネントに転送するために親コンポーネントによって使用されます。サブコンポーネントは、次の 2 つの方法でプロパティの変更をインターセプトできます:
入力プロパティ セッターを使用して、親コンポーネントの値の変更をインターセプトします。
ngOnchanges() を使用して、入力属性値の変更をインターセプトします。
@出力:
データ バインディング<!--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>
その効果は次のとおりです: (1. 親コンポーネントの入力、子コンポーネントは同期的に出力できます。2. 子コンポーネントの入力が必要です。(3.) ボタンをクリックして起動イベントをトリガーし、データを親コンポーネントに送信します。)
@Input : 親コンポーネントが入力している間、子コンポーネントは表示用のデータを同時に取得できます。コアコードは次のとおりです://父组件 parentPrint: any; //ts中,声明一个变量 [(ngModel)]="parentPrint" //html中,绑定变量,获取用户输入 //html中,将数据传给子组件 <app-child [fromParent]="parentPrint"></app-child> //子组件 @Input() fromParent; //ts中,用于直接接收从父组件获取的数据 [(ngModel)]="fromParent" //html中,用于显示数据
//子组件 private _fromParent: any; //私有变量,通过setter获取父组件的数据 @Input() //通过setter获取父组件的数据 set fromParent(fromParent: any) { this._fromParent = fromParent; } get fromParent(): any { return this._fromParent; }
@出力: 親コンポーネントが子コンポーネントからデータを受け取ると、子コンポーネントは EventEmitter プロパティを公開します。イベントが発生すると、子コンポーネントはこのプロパティを使用してイベントを発行します。親コンポーネントはこのイベント プロパティにバインドされ、イベントが発生すると応答します。コアコードは次のとおりです:
//子组件 @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; }
親コンポーネントのクラスが子コンポーネントのプロパティと値を読み取る必要がある場合または、子コンポーネントのメソッドを呼び出すと、子コンポーネントが ViewChild として親コンポーネントに挿入されます。 ViewChild を使用すると、その名前が示すように、サブコンポーネントの プロパティとメソッドを確認できます。
<!--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>
//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>
親コンポーネントとその子コンポーネントは同じサービスを共有し、家族がこのサービスを利用する 双方向コミュニケーション。 <!--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;
}
コンストラクター でそれ自体に挿入されます。親コンポーネントと子コンポーネントは一意の ID を持ちます。親コンポーネントと子コンポーネントのどちらがpush()メソッドを呼び出してデータをプッシュしても、双方がデータを受け取ることができます。このとき、IDに基づいてデータを親コンポーネントが使用するか子コンポーネントが使用するかを判断する必要があります。コアコードは次のとおりです:
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中文网其它相关文章!
推荐阅读:
以上がAngular2の親子コンポーネント通信方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。