Angular2,模板仅部分地使用ngAfterContentInit或ngAfterViewIni

2019-09-28 18:24发布

当试图访问该文档的DOM,我发现模板只是部分执行。 如果我使用setTimeout我可以解决该问题,但如何做到这一点的正确方法?

import { Component, Input, AfterContentInit } from '@angular/core';
import { AppService } from './app.service';

@Component({
    selector: 'tabs',
    templateUrl: './templates/app.html',
    providers: [ AppService ]
})

export class ShowBookmarksComponent implements AfterContentInit {

    private addListeners():void {
        let timeoutId = setTimeout(() => {
            let draggables = document.getElementsByClassName('session');
            console.log(draggables);
            console.log(draggables.length);
            for (let i = 0; i < draggables.length; i++) {
                console.log(i+'  '+draggables.length)
            }

            clearTimeout(timeoutId);
        }, 1000);
    }

    ngAfterContentInit() {
        this.appService.getBookmarkLists(this.sessions)
        .then(() => this.appService.getCurrentTabs(this.current_tabs))
        .then(() => this.addListeners());
    }

 }

appService被提供的模板将用于显示HTML数据。 模板:

<section class="current_tabs">
    <div class="session" *ngFor="let current_tab of get_keys(current_tabs);">
        <div class="whatever"></div>
    </div>
</section>

<section class="current_bookmarks">
    <div class="session" *ngFor="let session of get_keys(sessions);">
        <div class="whatever"></div>
    </div>
</section>

不知何故*,对应的部分sessions充满,但部分current_tabs 尚未填补。 无论this.sessionsthis.current_tabs调用之前填写正确addListeners

*由视为良好console.log(document.documentElement.innerHTML)的之前执行setTimeout

<section class="current_tabs">
    <!--template bindings={
  "ng-reflect-ng-for-of": ""
}-->
</section>

<section class="current_bookmarks">
    <!--template bindings={
  "ng-reflect-ng-for-of": "my_session_201 etc etc etc (correctly filled)

(执行setTimeout的内部时,则这两个被正确填充的)

在代码中,我要的是让let draggables = document.getElementsByClassName('session'); 正确检索,但是我没有得到内定义的那些<section class="current_tabs">因为它是尚未填充

编辑:更多的核心遍历打字稿字典中的角2

get_keys(obj : any) : Object {
    return Object.keys(obj);
}

Answer 1:

您需要等到current_tabs设置,然后调用变化检测明确( detectChanges()那么你可以添加听众直接算账:

constructor(private cdRef:ChangeDetectorRef){}

ngOnInit() {
    this.appService.getBookmarkLists(this.sessions)
    .then(() => this.appService.getCurrentTabs(this.current_tabs))
    .then(() => {
      this.cdRef.detectChanges();
      this.addListeners();
    });
}


Answer 2:

AfterViewChecked被称为非常频繁的角度来更新页面的状态,当新数据可用(绑定,Ajax请求等)。 你应该尽量把你的代码AfterContentInit当所有的外部数据加载到页面被调用。

看到https://angular.io/docs/ts/latest/api/core/index/AfterContentInit-class.html



Answer 3:

在解决Angular2,HostListener,我怎么可以针对一个元素? 我就可以根据类? 通过@GünterZöchbauer。 的问题是,在2个功能之间

    .then(() => this.appService.getCurrentTabs(this.current_tabs))
    .then(() => this.addListeners());

渲染器需要显示视图。 所以,我应该叫addListeners视图时更新。 与完成

    .then(() => {
        this.cdr.detectChanges();
        this.addListeners();
     });


文章来源: Angular2, templates are only partially executed when using ngAfterContentInit or ngAfterViewInit functions