最近碰到一個(gè)Angular中無(wú)法獲取DOM進(jìn)行實(shí)例化的問(wèn)題:記錄一下
項(xiàng)目使用Project Clarity框架,父組件中包含子組件,父組件中用彈框控制子組件的顯示和隱藏,當(dāng)彈框顯示時(shí),ng讀到父組件中的子組件,然后進(jìn)行加載渲染跨细,但是TS的執(zhí)行在DOM渲染完成之后,因?yàn)槲以噲D在ngAfterViewInit中獲取DOM元素河质,用getElementById取到的值居然是null冀惭,而getElementsByClassName獲取到對(duì)象,但是用數(shù)組方式訪問(wèn)時(shí)卻不識(shí)別掀鹅,百思不得其解
通過(guò)Debug我發(fā)現(xiàn)散休,當(dāng)子組件TS執(zhí)行時(shí),父組件頁(yè)面中的DOM并未加載出來(lái)乐尊,我使用定時(shí)器延遲之后就可以了戚丸,剛開(kāi)始我以為是ngIf 的問(wèn)題導(dǎo)致了這個(gè)執(zhí)行順序錯(cuò)誤,
為了解決這個(gè)問(wèn)題扔嵌,我另外寫(xiě)了個(gè)demo限府,父組件控制子組件的顯示,但是demo中并未出現(xiàn)項(xiàng)目中的問(wèn)題痢缎,我可以在ngAfterViewInit中獲取到子組件的DOM胁勺,因此我判斷是Project Clarity框架的原因,他的彈框使得DOM的加載慢了一點(diǎn)
但是使用ElementRef可以獲取到在框架中獲取不到的DOM独旷,但是因?yàn)轫?xiàng)目邏輯問(wèn)題署穗,這個(gè)方法并不能解決我的問(wèn)題
問(wèn)題找到了寥裂,但是沒(méi)有解決,很郁悶案疲!
總結(jié)整理一下收獲:主要是ng中獲取DOM元素的方法
- 如果子組件的ID是動(dòng)態(tài)由父組件傳遞的封恰,在ngOnInit中獲取不到DOM,因?yàn)閚gOnInit在DOM渲染之前
console.log(document.getElementById(`${this.mapId}`));//null
- 使用模版引用變量配合Viewchild可以獲取到DOM元素
- 使用ElementRef對(duì)象可以獲取當(dāng)前組件模版中DOM元素
<div *ngIf="isShow">
<app-zwf [mapId]="mapId"></app-zwf>
</div>
<button (click)="isShow=!isShow">顯示zwf</button>
<div #open>
模版引用變量
</div>
import { Component, OnInit, Input, ViewChild, TemplateRef, ElementRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-zwf',
templateUrl: './zwf.component.html',
styleUrls: ['./zwf.component.css']
})
export class ZwfComponent implements OnInit, AfterViewInit {
@ViewChild('open') open: TemplateRef<any>;
@Input() mapId;
// mapId = "open";
constructor(private el: ElementRef) { }
ngOnInit() {
// console.log(this.mapId);
// console.log(document.getElementById(`${this.mapId}`));
console.log(this.open);
// console.log(this.el);
console.log(this.el.nativeElement.querySelector('.d1'));
// this.el.nativeElement.querySelector('.d1').setAttribute('id', `${this.mapId}`)
console.log(document.getElementById(`${this.mapId}`));//null
console.log(document.getElementsByClassName('d1'));
}
ngAfterViewInit() {
console.log(document.getElementById(`${this.mapId}`));
console.log(document.getElementsByClassName('d1'));
}
}