父子組件的傳值仅淑,是mvvm框架中必然繞不過去的話題称勋,下面列舉在angular中父子組件傳值的各種方式。
一涯竟、通過輸入型綁定把數(shù)據(jù)從父組件傳到子組件
即帶有@Input裝飾器赡鲜,如下面兩種方式:
@[Input](https://angular.cn/api/core/Input)() hero: Hero;
@[Input](https://angular.cn/api/core/Input)('master') masterName: string;
父組件在引用子組件的標簽的時候,通過 [ ] 符號將父組件的變量名賦值給該變量庐船;
<app-hero-child *[ngFor](https://angular.cn/api/common/NgForOf)="let hero of heroes" [hero]="hero [master]="master"></app-hero-child>
子組件通過在變量名前面加上@Input裝飾器的方式银酬,可以從父組件取值,實現(xiàn)父子組件的傳值筐钟。
二揩瞪、通過setter截聽輸入屬性值的變化
在第一種方案的基礎上,使用一個輸入屬性setter篓冲,以攔截父組件中值的變化李破,并采取行動。
export class NameChildComponent {
private _name = '';
@[Input]()
set name(name: string) {
this._name = (name && name.trim()) || '<no
name set>';
}
get name(): string { return this._name; }
}
三壹将、通過ngOnChanges()來截聽輸入屬性值的變化
通過OnChanges生命周期鉤子接口的ngOnChanges()方法來檢測輸入屬性值的變化并做出回應嗤攻。
四、父組件監(jiān)聽子組件的事件
子組件暴露一個EventEmitter屬性诽俯,當事件發(fā)生時妇菱,子組件利用該屬性emits(向上彈射)事件,父組件綁定這個事件屬性暴区,并在事件發(fā)生時做出回應恶耽。
子組件的EventEmitter屬性是一個輸入屬性,通常帶有@Output裝飾器颜启。
子組件:
// template
<button (click)="vote(false)" [disabled]="didVote">Disagree</button>
// component
@Output() voted = new EventEmitter<boolean>();
vote(agreed: boolean) {
this.voted.emit(agreed);
}
父組件綁定一個事件處理器,用來響應子組件的事件浪讳。彈射出的事件缰盏,直接寫在父組件引入子組件的位置上。
<app-voter (voted)="onVoted($event)"></app-voter>
五淹遵、父子組件通過本地變量互動
父組件不能使用數(shù)據(jù)綁定來讀取子組件的屬性或者調用子組件的方法口猜。但可以在父組件模板里,新建一個本地變量來代表子組件透揣,然后利用這個變量來讀取子組件的屬性和調用子組件的方法济炎。
//父組件的template
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div class="seconds">{{timer.seconds}}</div>
<app-countdown-timer #timer></app-countdown-timer>
本地變量的寫法是(# + 變量名)
在父組件中,把本地變量(#timer)放到子組件標簽(<countdown-timer>)中辐真,用來代表子組件须尚,該父組件模板就得到子組件的引用崖堤,可以在父組件模板訪問子組件的屬性和方法。
六耐床、父組件調用@ViewChild()
上面那種本地變量的方式密幔,有局限性,只能在父組件的模板中使用撩轰。如果在父組件的類中讀取子組件的屬性方法胯甩,就不能使用本地變量了。
當父組件類需要這種訪問時堪嫂,可以把子組件作為ViewChild偎箫,注入到父組件中。
@ViewChild(CountdownTimerComponent)
private timerComponent: CountdownTimerComponent;
首先皆串,你必須導入對裝飾器ViewChild
以及生命周期鉤子 AfterViewInit
的引用淹办。
接著,通過 ViewChild
屬性裝飾器愚战,將子組件 CountdownTimerComponent
注入到私有屬性 timerComponent
里面娇唯。
ngAfterViewInit()
生命周期鉤子是非常重要的一步。被注入的計時器組件只有在 Angular 顯示了父組件視圖之后才能訪問.所以需要加上setTimeout()來等下一輪寂玲。
ngAfterViewInit() {
setTimeout(() => this.seconds = () =>
this.timerComponent.seconds, 0);
}
七塔插、通過服務來通訊
不會!rxjs看不懂M赜础O胄怼!
不過可以通過redux存在統(tǒng)一的store樹里面断序,增刪改查都從這里取流纹,變相實現(xiàn)傳值。