連續發了 20 幾天的文,能講的也都講了,邁向神乎其技之路只剩下掌握小地方了吧!
之前介紹過 <ng-content>
跟 ContentChild
,還有個很類似的是 @ViewChild
裝飾器,接著就來看看這是甚麼吧!
這篇建議搭配前一篇一起看。
直接來看範例,這個範例大致跟 @ContentChild
的範例很像,但做了一點修改,晚點我們會做比較。
import {Component} from 'angular2/core';
import {ParentComponent} from './parent';
import {ChildComponent} from './child';
@Component({
selector: 'my-app',
template: `
<h2>App Component</h2>
<my-parent></my-parent>
`,
directives:[ParentComponent,ChildComponent]
})
export class AppComponent {
}
注意到 <my-parent></my-parent>
裡面不用包 <my-child>
了。
import {Component} from 'angular2/core';
@Component({
selector: 'my-child',
template: `
<div>Child Component</div>
`
})
export class ChildComponent {
name:string = 'childName';
}
child
保持不變
import {Component,ViewChild,AfterViewInit} from 'angular2/core';
import {ChildComponent} from './child';
@Component({
selector: 'my-parent',
template: `
<div>Parent Component</div>
<my-child></my-child>
`,
directives:[ChildComponent]
})
export class ParentComponent implements AfterViewInit{
@ViewChild(ChildComponent)
child:ChildComponent;
ngAfterViewInit() {
console.log(this.child)
}
}
改成用 @ViewChild
,一樣可以取得 child 的組件內容,不過要在 AfterViewInit
之後才會生效。
如果改成這樣
template: `
<div>Parent Component</div>
<my-child></my-child>
<p>{{child.name}}</p>
`
則會
因為你在他生效前就呼叫了!
可以看到 child 在 parent 中被呼叫了
所以 @ViewChild
跟直接引入組件使用差在哪?
差在如果我們在 parent 的模板沒有使用到 <my-child>
的話,@ViewChild
就會無法調用 child 的組件內容。而如果直接引用 child 組件的話,不使用標籤也沒關係。
@ContentChild
是組件中 selector
標籤閉合之間的子組件,意思就是在 AppComponent
中 <my-parent>
裡面必須要包含 <my-child>
,換言之決定權在「使用 <my-parent>
的組件」手上,也就是有 @ContentChild
的上一層。@ViewChild
是組件模板當中的子組件,決定權在當前組件。兩者都有複數形式,@ContentChildren
和 @ViewChildren
什麼時候獲取到子組件的值?
@ContentChild
在父組件生命週期函數 ngAfterContentInit
之後可以獲取到@ViewChild
在父組件生命週期函 ngAfterViewInit
之後可以獲取到