简体   繁体   中英

Angular2 Wait DOM element to load

I have Component which has a member array variable. This array is bind to DOM with *ngFor. When I add new variable to array my view changes accordingly. Array holds tab names and initially it is set to have only 1 tab. When I refresh page array reinitialized which is what I was expecting. But when I logout and then log back in(router navigation) I see all previous tabs. It is weird to me, because if I console.log(myTabs) array has only 1 element(homeTab).

UPDATE:

.html

<div style="display: table-caption" id="notify-tabs">
    <ul class="nav nav-tabs" role="tablist" id="nav-bar">
        <li role="presentation" data-toggle="tab" id="homeTab" [class.active]="activeTab==='homeTab'"><a (click)="setValues('home')">Home</a>
        <li role="presentation" *ngFor="let tab of myTabs" data-toggle="tab" id={{tab}} [class.active]="activeTab===tab.toString()"><a (click)="setValues(tab)">{{tab}}</a>
    </ul>
</div>

.component.ts

@Component({

    selector: 'notify-homepage',
        templateUrl: 'app/home/home.component.html',
        styleUrls: ['styles/css/bootstrap.min.css', 'styles/home.css'],
        directives: [DynamicComponent, TileComponent, MapComponent, HeaderComponent, ConversationComponent, ROUTER_DIRECTIVES]
})
export class HomeComponent{
    public myTabs: number[] = [21442];
    public activeTab: string = 'homeTab';

    ngOnInit() {
    //Assume fully operating MapService here
    this.subscription = this.mapService.conversationId.subscribe(
        (id: number) => {
            this.myTabs.push(id);
            this.setValues(id);
            this.activeTab = id.toString();               
        })
    }
    ngOnDestroy() {
    this.subscription.unsubscribe();
    ...
}
}

map.service.ts

@Injectable()
export class MapService {
    private conversationIdSource = new ReplaySubject<number>();
    public conversationId = this.conversationIdSource.asObservable();

    ...

     showConversation(id: number) {
         this.conversationIdSource.next(id);
     }
}

Check Lifecycle hooks :

  1. OnChanges https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges
  2. DoCheck https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#docheck

They help tracking changing in Input and local variables.

OnChanges for Input variables:

ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
  for (let propName in changes) {
    let chng = changes[propName];
    let cur  = JSON.stringify(chng.currentValue);
    let prev = JSON.stringify(chng.previousValue);
    this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
  }
}

DoCheck for everything:

ngDoCheck() {
  if (this.hero.name !== this.oldHeroName) {
    this.changeDetected = true;
    this.changeLog.push(`DoCheck: Hero name changed to "${this.hero.name}" from "${this.oldHeroName}"`);
    this.oldHeroName = this.hero.name;
  }
}

The answer of @Andrei works, but in my opinion there's a better and more elegant solution.

Just use a combination of @ViewChild() and setters.

For example:

// component.html

<ng-el ... #myElement>

// component.ts

@ViewChild('myElement') set(el) {
  if (el) {
    console.log('element loaded!');
  }
}

Try this :

while(!document.getElementById('print-section')) {
  await new Promise(resolve => setTimeout(resolve, 100));
}

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