我已经看过将代码包装在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。
答案 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