因為會忘,所以要寫下來

Angular ElementRef、TemplateRef、viewContainerRef 的區別

今天就來聊聊 ElementRefTemplateRefviewContainerRef,者實說,在這之前一直都沒很認真搞懂這部份 就趁著這次機會一起來看看吧!

ElementRef

用於檢視 HTML DOM 元素,可以在瀏覽器中取得 DOM 的原生 Element

ElementRef

.html

<span #elRef>I am span</span>

.ts

export class TemplateComponent implements AfterViewInit {
  @ViewChild("elRef") elRef!: ElementRef;

  ngAfterViewInit() {
    console.log("ElementRef", this.elRef.nativeElement.textContent); //I am span
  }
}

TemplateRef

屬於模板元素的一種,在頁面裡不會呈現,但可透過 ViewContainerRef 將它渲染出來

.html

<ng-template #tpRef><span>I am span in template</span></ng-template>

.ts

export class TemplateComponent implements AfterViewInit {
  @ViewChild('tpRef') tplRef!: TemplateRef<any>;

  ngAfterViewInit() {
    console.log("TemplateRef", this.tplRef.elementRef.nativeElement); //<!--container-->
    console.log("TemplateRef", this.tplRef.elementRef.textContent); //container
  }
}

這裡可以看到 把 TemplateRef console 出來會是一個 container,在 html 上是就只是一個註解。


viewContainerRef

它用來操控顯示的內容 有著 host 與 embedded view 來建立動態顯示

接續著剛剛的 TemplateRef

.html

<span>I am first span</span>
<ng-container #vc></ng-container>
<span>I am last span</span>

<ng-template #tpRef
  ><span style="color:red;">I am span in template</span></ng-template
>

<!-- 加兩顆按鈕,試著操控 TemplateRef -->
<button (click)="onRemoveTpl()">removeTpl</button>
<button (click)="onAddTpl()">addTpl</button>

.ts

export class TemplateComponent implements AfterViewInit {
  @ViewChild('tpRef') tplRef!: TemplateRef<any>;

  ngAfterViewInit() {
    const elem = this.tplRef.createEmbeddedView(null);
    this.vc.insert(elem);
  }

  onRemoveTpl() {
    this.vc.remove();
  }

  onAddTpl() {
    this.vc.createEmbeddedView(this.tplRef);
  }
}

試著玩玩看範例吧!

範例:https://stackblitz.com/edit/angular-ivy-sffarv


參考資料:

Exploring Angular DOM manipulation techniques using ViewContainerRef

Angular 2 TemplateRef & ViewContainerRef


對這篇文章有什麼想法嗎?

Copyright © 2022 Mandy. All rights reserved. Build with Angular