我有一个Angular2组件,它具有在OnInit事件中初始化的自定义第三方JQuery插件(我们必须使用并且无法更改)。但是,这个第三方库可以自由使用setIntervals。如果我离开视图,则间隔仍处于活动状态,而在其他视图上,它们会一直触发窗口小部件行为。
第三方组件无法销毁它或清除间隔(这不是很好)。我原本希望在Angular2 OnDestroy方法中调用destroy()或类似的东西。
我以为我应该可以使用Zone进行清理。我做了以下事情:
constructor(elementRef: ElementRef, public zone: NgZone) {
}
ngOnInit() {
this.zone.runOutsideAngular(() => {
$(this.elementRef).3rdPartyWidgetStart();
});}
ngOnDestroy() {
var componentzone=this.zone;
//So do something here to clear intervals set within Zone???
}
我认为当我离开时它会清除间隔。然而,情况似乎并非如此。我还尝试了run
而不是runOutsideAngular
,但它似乎没有帮助。然后我认为Zone应该知道已设置的所有间隔,我可以通过它清除它们。它确实似乎知道它们然而似乎无法访问列表并清除?使用Angular 2 RC的任何想法 - 或者如果我只是做了Zones完全错误的事情让我知道。这对我来说是全新的
答案 0 :(得分:1)
1)run
vs runOutsideAngular
调用runOutsideAngular
时,在您的插件启动异步操作(setTimeout
,evetns,XHR,..)后,不会触发更改检测。
调用run
时(更好的是直接调用3rdPartyWidgetStart
)更改检测将在任何异步操作后执行。
选择适合您项目的方式(即你需要在setTiemout,事件之后运行CD吗?)。
2)清除setTimeouts
你可以做的是分叉当前区域传递ZoneDelegate
,这会累积计时器ID并在ngOnDestroy
中取消它们。
但解决这个问题的最佳方法可能就是修复jQuery插件。
答案 1 :(得分:1)
我应该说,你这样做是冒自己的风险。直接使用区域:
Zone.current.fork({
name: 'jquery', onScheduleTask: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
task: Task)=>
{
if(task.source === 'setInterval'){
console.log('capture', task);
//data has handleId property, interval id
this.interval = task.data;
}
return parentZoneDelegate.scheduleTask(targetZone, task);
}
}).run(()=>
{
setInterval(()=>
{
console.log('jquery interval', Zone.current);
}, 5000);
});
代码中的某处:
clearInterval(this.interval.handleId);
这段代码很可能缺少一些检查,阅读文档。此外,我不确定角度是否正常。