@ViewChild() decorator 一開始是在存取 child component 時學到的,事實上 @ViewChild() 還有其他使用方法。 
Version
Node.js 8.9.3
Angular CLI 1.6.2
Angular 5.2
Component
 使用 @ViewChild() 存取 child component。 
 
 
-  
counter初始值為2 -  按 
+則counter+ 1,按-則counter-1 
Architecture
 
 
-  
AppComponent負責處理<button/>;CounterComponent負責顯示counter -  
AppComponent相當於 parent component,CounterComponent相當於 child component -  
AppComponent直接呼叫CounterComponent的 method 改變counter;AppComponent也可直接讀取CounterComponent的 property 
Implementation
AppComponent
 
 
app.component.html
<button (click)="onAddOneClick()">+</button> <button (click)="onMinusOneClick()">-</button> <p></p> <app-counter></app-counter>
 將 2 個 <button/> 留在 AppComponent 內。 
 counter 的顯示由 <app-counter/> 負責。 
app.component.ts
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { CounterComponent } from './counter/counter.component';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild(CounterComponent)
  private counterComponent: CounterComponent;
  ngAfterViewInit(): void {
    console.log(this.counterComponent.counter);
  }
  onAddOneClick() {
    this.counterComponent.addOne();
  }
  onMinusOneClick() {
    this.counterComponent.minusOne();
  }
}
 
  10 行
@ViewChild(CounterComponent) private counterComponent: CounterComponent;
 Angular 允許我們在 parent component 透過 @ViewChild() decorator 宣告 child component,藉此存取 child component 的 public field 與 method。 
 @ViewChild() 第一個參數傳入 child component 的型別。 
第 9 行
export class AppComponent implements AfterViewInit {
  ngAfterViewInit(): void {
    console.log(this.counterComponent.counter);
  }
}
 
   若要透過 @ViewChild() 存取 child component 的 public field,則必須在 ngAfterViewInit() lifecycle hook 才可抓的到,不可以在 ngOnInit() 。 
17 行
onAddOneClick() {
  this.counterComponent.addOne();
}
 
   若要透過 @ViewChild() 存取 child component 的 public method,則無此限制。 
CounterComponent
 
 
counter.component.html
{{ counter }}
 
   負責顯示 counter 。 
counter.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'app-counter',
  templateUrl: './counter.component.html',
  styleUrls: ['./counter.component.css']
})
export class CounterComponent {
  counter = 2;
  addOne() {
    this.counter++;
  }
  minusOne() {
    this.counter--;
  }
}
 
  沒有特別的部分需要講解。
  
 當 parent component 要存取 child component 時,使用 @ViewChild() 宣告 child decorator,public field 可在 ngAfterViewInit() 存取,public method 則無此限制 
Directive
 當使用 directive 套用在 HTML 上時,可以藉由 @ViewChild() 取得 directive 的物件實體,藉此控制 directive。 
Implementation
ChangeColorDirective
change-color.directive.ts
import { AfterViewInit, Directive, ElementRef } from '@angular/core';
@Directive({
  selector: '[appChangeColor]'
})
export class ChangeColorDirective implements AfterViewInit {
  constructor(private elementRef: ElementRef) {
  }
  ngAfterViewInit(): void {
    this.elementRef.nativeElement.style.color = 'red';
  }
  change(changedColor: string) {
    this.elementRef.nativeElement.style.color = changedColor;
  }
}
 
   使用 Angular CLI 的 ng g d ChangeColor 建立 ChangeColor directive。 
15 行
change(changedColor: string) {
  this.elementRef.nativeElement.style.color = changedColor;
}
 
   ChangeColor directive 提供了 change() 修改 color 。 
AppComponent
app.component.html
<p appChangeColor>{{ title }}</p>
<p></p>
<button (click)="onChangeColorClick()">Change Color</button>
 
   <p> 套用了 ChangeColor directive。 
app.component.ts
import { Component, ViewChild } from '@angular/core';
import { ChangeColorDirective } from './change-color.directive';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild(ChangeColorDirective)
  private changeColorDirective: ChangeColorDirective;
  title = 'app';
  onChangeColorClick() {
    this.changeColorDirective.change('green');
  }
}
 
  10 行
@ViewChild(ChangeColorDirective) private changeColorDirective: ChangeColorDirective;
 為了使用 ChangeColor directive 的 change() ,特別使用 @ViewChild() 取得 ChangeColor directive 的物件實體,如此就能使用 change() 。 
DOM Element
 最後一個常用的 @ViewChild() 方式,是藉由 template reference varibale 存取 DOM element。 
Implementation
AppComponent
app.component.html
Name: <input type="text" #name>
<p></p>
<button (click)="onSubmitClick()">Submit</button>
<p></p>
{{ yourName }}
 
   若要在 JavaScript 存取 HTML,傳統會使用 id 或 CSS selector,在 Angular 提出新的方法,我們可以為 HTML 加上 # 開頭的 template reference variable。 
app.component.ts
import { Component, ElementRef, ViewChild } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  yourName: string;
  @ViewChild('name')
  private name: ElementRef;
  onSubmitClick() {
    this.yourName = this.name.nativeElement.value;
  }
}
 
  11 行
@ViewChild('name')
private name: ElementRef;
 
   使用 @ViewChild() 取得 DOM element 的物件實體,參數以字串傳入 template reference variable 的字串名稱。 
 注意其型別為 ElementRef 。 
14 行
onSubmitClick() {
  this.yourName = this.name.nativeElement.value;
}
 
   如此就能在 TypeScript 藉由 @ViewChild() 所宣告的變數,存取 DOM element 物件。 
Conclusion
-  傳統都只將 
@ViewChild()用在存取 child component,事實上@ViewChild()還可以用在存取 directive 與 DOM element。 
Sample Code
完整的範例可以在我的 GitHub 上找到
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。