简体   繁体   中英

How to wait in Angular 7 until DOM changed ready?

I have a list of entries. When I click on such an entry a HTTP request is done, data will be loaded and presented in a table. So far so good.

Now I try to create an export function to output all tables at once. The abstracted code looks like this:

this.objectlist.forEach(entry => {

    this.getDataFromHTTP(entry).subscribe(response => {
        tabledata.push(this.getTableDOM());
    })

})

In the function getTableDOM() I do something like let table = document.getElementsByClassName(data.classname); . The code itself runs when I click every entry. But it doesn't work within the forEach() .

The real problem is that the getTableDOM() returns an empty result, because the DOM isn't ready when it is called.

So my question is: how can I wait until DOM changes are done before I call getTableDOM() . Or maybe my approach to achieve my goal is completely wrong. But if so: how can I do it otherwise?

Thx for your help! Lars

You shouldn't use DOM as a source of data like you are doing. Anyways, you can detect the changes manually to render the DOM and in next tick export the content.

constructor(private changeDetector : ChangeDetectorRef) {}

this.objectlist.forEach(entry => {
    this.getDataFromHTTP(entry).subscribe(response => {
        this.changeDetector.detectChanges();//if using push stratagy
        setTimeout(_=>tabledata.push(this.getTableDOM()));
    })
})

Also check this question

You can mark your tables and access them using viewChildren

@ViewChildren("mytable") mytable;

this.mytable.changes.subscribe((el)=>{
    /*check if desired table node exists on el*/
});

Please see this DEMO I've created, hopefully, it'll get you going in the right direction. Like others have mentioned from what you've provided it's difficult to get the full picture. I think what you're looking for is something like OnChanges , I've included relevant example code below. I've also included in the demo a forkJoin example.

import {
  Component,
  Input,
  OnChanges,
  SimpleChanges
} from '@angular/core';

@Component({
  selector: 'on-change',
  template: `
        <pre>
            {{changes | json}}
        </pre>
    `
})
export class OnChangeComponent implements OnChanges {
  @Input() data: any;
  changes;
  constructor() {}

  ngOnChanges(changes: SimpleChanges) {
    this.changes = changes;
  }
}

This will check every 2 secs ...

public static void AngWait(){
    WebDriverWait jsWait jsExec = (JavascriptExecutor) driver;
    String angular5Check = (String) jsExec.executeScript("return getAllAngularRootElements()[0].attributes['ng-version'].value");
    System.out.println(angular5Check);
    if (angular5Check != null) {
        do {
            angularPageLoaded = (Boolean) jsExec.executeScript("return window.getAllAngularTestabilities().findIndex(x=>!x.isStable()) === -1");
            System.out.println("in loop => "+angularPageLoaded);
            Thread.sleep(2000);

        } while (!angularPageLoaded);

        System.out.println("outside loop => "+angularPageLoaded);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM