iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 27
2
Modern Web

Angular 2 之 30 天邁向神乎其技之路系列 第 27

[Day 27] Angular 2 裝飾器 @ViewChild

前言

連續發了 20 幾天的文,能講的也都講了,邁向神乎其技之路只剩下掌握小地方了吧!
之前介紹過 <ng-content>ContentChild,還有個很類似的是 @ViewChild裝飾器,接著就來看看這是甚麼吧!

這篇建議搭配前一篇一起看。

@ViewChild

直接來看範例,這個範例大致跟 @ContentChild範例很像,但做了一點修改,晚點我們會做比較。

app.ts

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> 了。

child.ts

import {Component} from 'angular2/core';

@Component({
    selector: 'my-child',
    template: `
        <div>Child Component</div>
    `
})
export class ChildComponent {
    name:string = 'childName';
}

child 保持不變

parent.ts

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>
    `

則會

因為你在他生效前就呼叫了!


Plunker

可以看到 child 在 parent 中被呼叫了

所以 @ViewChild 跟直接引入組件使用差在哪?

差在如果我們在 parent 的模板沒有使用到 <my-child> 的話,@ViewChild 就會無法調用 child 的組件內容。而如果直接引用 child 組件的話,不使用標籤也沒關係。

區分 @ContentChild 和 @ViewChild

  • @ContentChild 是組件中 selector 標籤閉合之間的子組件,意思就是在 AppComponent<my-parent> 裡面必須要包含 <my-child>,換言之決定權在「使用 <my-parent> 的組件」手上,也就是有 @ContentChild 的上一層。
  • @ViewChild 是組件模板當中的子組件,決定權在當前組件。

兩者都有複數形式,@ContentChildren@ViewChildren

什麼時候獲取到子組件的值?

  • @ContentChild 在父組件生命週期函數 ngAfterContentInit 之後可以獲取到
  • @ViewChild 在父組件生命週期函 ngAfterViewInit 之後可以獲取到

上一篇
[Day 26] Angular 2 裝飾器 @ContentChild
下一篇
[Day 28] Angular 2 製作 tab 元件
系列文
Angular 2 之 30 天邁向神乎其技之路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言