是否可以清除NGZone中设置的所有间隔?

时间:2016-05-17 21:44:41

标签: javascript typescript angular zone

我有一个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完全错误的事情让我知道。这对我来说是全新的

2 个答案:

答案 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);

这段代码很可能缺少一些检查,阅读文档。此外,我不确定角度是否正常。