angular

[Angular] 使用 @ViewChild 取得操作 DOM 屬性

周志衠 Jed Jhou 2020/12/31 17:44:45
162

在使用 Angular 開發時因為已內建基本的資料繫結功能,我們只要在 html 範本中依照繫結語法即可簡單快速地完成對指定的 DOM 物件完成繫結,只要變更 component.ts 的資料內容,DOM 的值就會跟著變動,不用像使用 jquery 需要先一個一個取得指定物件在對其操作,這對常需要使用動態表格的功能開發上減少了許多負擔,但有時候我們還是會依照需求在某個時間對單獨的 DOM 物件進行操作或取得屬性值來判斷,例如使用 fabric.js,等需要對 canvas 設定大小的操作,通常我們不會寫死,而是依照其上一層的 div 元素大小來動態設定 canvas 畫布大小,這時候我們可以用 @ViewChild 屬性裝飾器來於 component.ts 操作 DOM 物件內容。

 

 

使用說明

示範使用 fabricjs 依照動態寬高設定 canvas 大小

app.component.scss

.viewport {
     width: 100%;
     height: calc(100vh - 250px);
}

app.component.html

    <div #viewport class="viewport">
      <canvas id="canvas" style="border:1px dashed"></canvas>
    </div>

app.component.ts

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { Canvas } from 'fabric/fabric-impl';
import { fabric } from 'fabric';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit {

  private canvas: Canvas;

 @ViewChild('viewport', { static: true }) viewportDOM: ElementRef;

  constructor() { }

  ngOnInit(): void {
  
  this.canvas = new fabric.Canvas('canvas');
  this.canvas.setWidth(this.viewportDOM.nativeElement.offsetWidth);
  this.canvas.setHeight(this.viewportDOM.nativeElement.offsetHeight);
  this.canvas.renderAll();
  }
}

注意這裡使用方式情境和官網範例點不太一樣,這裡多設定了一個 static 的選項,因為我想在 ngOnInit() 時就完成操作,而 static 參數是指我們要操作的 DOM 在 component.html 一開始就存在,不是透過 *ngIf 或 *ngFor 等結構型指令去產生的,如果要操作的 DOM 是由結構型指令產生,可以不用加上 static 參數,因為不加就是預設 static : false,這時候就要在 ngAfterViewInit() 才能抓到 @ViewChild 的內容,否則會報錯。

周志衠 Jed Jhou