ElementRef 顧名思義是元素參閱
在實際應用中獲取視圖層的dom元素,藉助Angular提供的依賴注入機制,輕鬆訪問到dom元素
ElementRef的定義
export class ElementRef {
public nativeElement: any;
constructor(nativeElement: any) { this.nativeElement = nativeElement; }
}
ElementRef的應用
先來介紹一下需求,我們想在頁面成功渲染後,獲取頁面中的div元素,並改變該div元素的背景顏色。接下來我們一步步實現這個需求
首先我們要先獲取div元素,在文中"ElementRef的作用"部分,我們已經提到可以利用Angular提供的強大的依賴注入特性,獲取封裝後的native元素。在瀏覽器中native元素就是DOM元素,我們只要先獲取my-app元素,然後利用querySelector API就能獲取頁面中 div元素。具體代碼如下
import { Component, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Welcome to Angular World</h1>
<div>Hello {{ name }}</div>
`,
})
export class AppComponent {
name: string = 'mh';
constructor(private elementRef: ElementRef) {
let divEle = this.elementRef.nativeElement.querySelector('div');
console.dir(divEle);
}
}
運行上面代碼,在控制檯中沒有出現異常,但是輸出的結果卻是null。什麼情況?沒有拋出異常,我們可以推斷this.elementRef.nativeElement 這個對象是存在,但卻找不到它的子元素,那應該是在調用構造函數的時候,my-app元素下的子元素還未創建。那怎麼解決這個問題呢?angular內部提供了聲明週期鉤子,那我們來改造一波:
import { Component, ElementRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Welcome to Angular World</h1>
<div>Hello {{ name }}</div>
`,
})
export class AppComponent {
name: string = 'xiaowang';
// 在構造函數中 this.elementRef = elementRef 是可選的,編譯時會自動賦值
// function AppComponent(elementRef) { this.elementRef = elementRef; }
constructor(private elementRef: ElementRef) { }
ngAfterViewInit() { // 模板中的元素已創建完成
console.dir(this.elementRef.nativeElement.querySelector('div'));
// let greetDiv: HTMLElement = this.elementRef.nativeElement.querySelector('div');
// greetDiv.style.backgroundColor = 'red';
}
}
上述的代碼中,我們用了ngAfterViewInit這個鉤子,也是顧名思義,在視圖初始化完畢之後調用,這樣就可以成功的獲取template中的dom節點元素啦