Wait for querySelectorAll

三世轮回 提交于 2019-12-24 07:33:24

问题


I am developing an app via Ionic Framework. I upgraded my app from Ionic 3 to Ionic 4. Now hyperlinks do not work anymore. The HTML content is loading dynamically based on the chosen page. I've read I have to set new eventListeners for my clicks on my a elements.

I am trying:

ngOnInit()
{
    this.objAnswerService.getAntworten(objFrage).then(arrAnswer =>
    {
        this.arrAnswers = arrAnswer;
    }
}

ngAfterViewInit()
{
    console.log('_enableDynamicHyperlinks');
    this._enableDynamicHyperlinks();
}

private _enableDynamicHyperlinks()
{
    let arrUrls = this._element.nativeElement.querySelectorAll('a');
    console.log(JSON.stringify(arrUrls)); // No elements
    console.log(arrUrls); // Correct elements
    arrUrls.forEach((objUrl) =>{
        console.log('do something'); // Never reached because 0 elements
    });
}

answer.page.html

<div *ngIf="arrAnswers">
    <div *ngFor="let objAnswer of arrAnswers"
         class="antworten">
        <div *ngIf="objAnswer"
             class="antwort">
            <div [innerHTML]="safeHtml(objAnswer.strText)"></div>
        </div>
    </div>
</div>

How can I wait for querySelectorAll() to find all existing elements?


回答1:


since this.arrAnswers is initialized in a Promise it is undefined when the component fiirst loads. As a result of this <div *ngIf="arrAnswers"> evaluates to false and there are no elements for querySelectorAll to return on ngOnInit or ngAfterViewInit because they both gets called once during component lifecycle.

what you need is ngAfterViewChecked to be called when this.arrAnswers is initialized and dom is updated.

  ngAfterViewChecked() {
    console.log('_enableDynamicHyperlinks');
    if (!this._element) return;
    let arrUrls = this._element.nativeElement.querySelectorAll('p');
    console.log("arrUrls.length:", arrUrls.length);
    console.log("arrUrls:", arrUrls);
  }

also do not forget to use { static: false } on @ViewChild as explained here.

here is a simple demo




回答2:


The better way to handle this is using angular lifecycle hook.

If it doesn't work with ngOnInit() you can take a look at ngAfterViewInit()which respond after Angular initializes the component's views and child views / the view that a directive is in.

ngAfterViewInit() {
   let arrUrls = this._element.nativeElement.querySelectorAll('a');

    console.log(JSON.stringify(arrUrls)); // No elements
    console.log(arrUrls); // Correct elements

    arrUrls.forEach((objUrl) =>{
        console.log('do smthng'); //Never reached because 0 elements
    });
}


来源:https://stackoverflow.com/questions/56717820/wait-for-queryselectorall

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!