Можно ли очистить все интервалы, установленные в NGZone?

У меня есть компонент Angular2, который имеет собственный сторонний плагин JQuery (который мы должны использовать и не можем изменять), инициализированный в нем в событии OnInit. Однако эта сторонняя библиотека свободно использует setIntervals. Если я ухожу от представления, интервалы все еще активны, и на других представлениях они продолжают вызывать поведение виджета.

Сторонний компонент не имеет возможности уничтожить его или очистить интервалы (что не очень хорошо). Я надеялся просто вызвать destroy() или подобное в методе Angular2 OnDestroy.

Я думал, что смогу использовать Зону для очистки. Я сделал следующее:

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 и это, похоже, не помогло. Затем я подумал, что Зона должна знать все интервалы, которые были установлены, и я могу очистить их через это. Кажется, что они их знают, но не представляется возможным получить доступ к списку и очистить? Любые идеи, использующие Angular 2 RC - в качестве альтернативы, если я просто делаю что-то совершенно не так с Zone s, дайте мне знать. Это все новое для меня

2 ответа

Решение

Я должен сказать, что вы делаете это на свой страх и риск. Используйте зону напрямую:

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

В этом коде, скорее всего, отсутствуют некоторые проверки, прочитайте документацию. Также я не уверен, что с этим все в порядке.

1) run против runOutsideAngular

При звонке runOutsideAngularобнаружение изменений не сработает после асинхронных операций (setTimeout, evetns, XHR,..) инициировано из вашего плагина.

При звонке run (лучше позвонить 3rdPartyWidgetStart непосредственно) обнаружение изменений будет выполнено после любой асинхронной операции.

Выберите любой способ, который работает для ваших проектов (т.е. вам нужно запустить CD после setTiemout, events,...?).

2) Очистить setTimeouts

Что вы могли бы сделать, это разветвить текущую зону, передавая ZoneDelegate что бы накапливать идентификаторы таймера и отменять их в вашем ngOnDestroy,

Но лучший способ справиться с этим, вероятно, исправить плагин jQuery.

Другие вопросы по тегам