Angular 2:setTimeout适用于所有内容?

时间:2016-04-12 12:17:40

标签: jquery angular settimeout

我已经看过将代码包装在setTimeout函数中的示例,以避免在没有等待的数据的情况下生成模板/组件。我想使用jQuery bootstrap-multiselect来显示组织列表。

ngOnInit(){
  this._panelService.getOrgs()
    .subscribe(
      orgs => this.orgs = orgs,
      error => alert('There was an error connecting to the API'),
      () => setTimeout(() => jQuery('#organizations').multiselect(), 0));
}

我也在其他地方使用过它。在这种情况下,我在删除后调用API以触发* ngFor中的更改:

deleteBoard(panelId: number, boardId: number) {
  this._boardService.deleteBoard(panelId, boardId)
    .subscribe(
      boards => this.panel.boards = boards,
      error => alert('There was an error contacting the API.'),
      () => setTimeout(this._boardService.getAvailableRanks(panelId)
        .subscribe(ranks => this.updatedRanks = ranks), 0));
}

* ng除非我使用setTimeout,否则不会检测到更改。我错过了什么?

我正在使用beta 14。

4 个答案:

答案 0 :(得分:5)

角度变化检测将在每个异步事件后自动运行,如果异步事件由Zone.js进行猴子修补。在更改检测期间,检查NgFor绑定是否有更改,如果发现任何更改,则更新DOM。

我假设deleteBoard()使用某种异步事件,但该事件可能不会被Zone.js修补。 setTimeout()是猴子修补的,所以调用它会触发变化检测。

您可以注入ChangeDetectorRef而不是setTimeout(),并调用其detectChanges()方法,该方法将检测此组件及其后代的更改。这是手动触发变化检测的另一种方法。

但是,这两种方法之间存在差异。使用setTimeout(),浏览器有机会在调用回调函数之前呈现视图。有时你需要这个。使用detectChanges(),在浏览器有机会呈现视图之前运行更改检测。如果可以,请使用detectChanges(),因为它更有效(执行更改检测周期少一个)。

答案 1 :(得分:0)

document.createElement()需要能够完成其工作。为此,您需要使用var script = document.createElement('script'); script.onload = function() { // put here code which depends on Firebase to be loaded... }; script.type = "text/javascript"; script.src = "https://cdn.firebase.com/v0/firebase.js"; document.head.appendChild(script); 将对*ngFor的调用排入事件队列。如果您同步运行它,jQuery将无法获得处理更新的时间段。

答案 2 :(得分:0)

如果您想等待删除调用完成然后重新加载排名,我会利用flatMap运算符:

deleteBoard(panelId: number, boardId: number) {
  this._boardService.deleteBoard(panelId, boardId)
    .map(res => res.json())
    .flatMap((board) => {
      this.panel.boards = boards,
      return this._boardService.getAvailableRanks(panelId)
        .map(res => res.json());
    })
    .subscribe(ranks => this.updatedRanks = ranks));
}

答案 3 :(得分:0)

听起来你需要包含zone.js. 它将帮助Angular实现变化(想想它几乎就像消化在Angular1中的方式)

   "zone.js": "0.6.10" // add it in dependencies