1

在尝试访问文档的 DOM 时,我发现模板仅部分执行。如果我使用 asetTimeout我可以解决这个问题,但是正确的方法是什么?

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_tabsaddListeners

*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">因为它尚未填充

编辑:在 Angular 2 中对 TypeScript 字典进行更核心的迭代

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

3 回答 3

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();
    });
}
于 2017-01-17T19:35:05.967 回答
0

当有新数据(绑定、ajax 请求等)时,Angular 会非常频繁地调用 AfterViewChecked 来更新页面的状态。您应该尝试将代码放在 AfterContentInit 中,当所有外部数据加载到页面时调用该代码。

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

于 2017-01-17T11:25:34.710 回答
0

Angular2 中解决,HostListener,我如何定位一个元素?我可以根据班级定位吗?@GünterZöchbauer。问题在于这两个功能之间

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

渲染器需要显示视图。所以我应该addListeners在视图更新时打电话。完成

    .then(() => {
        this.cdr.detectChanges();
        this.addListeners();
     });
于 2017-01-17T16:01:02.780 回答