Можно ли очистить все интервалы, установленные в 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.