Я пытаюсь реализовать метод, при котором изменение вкладки материала angular происходит через фиксированный интервал времени. Я пробовал использовать setInterval в JavaScript, но он работает не очень надежно (смена вкладки происходит случайным образом). Приведенный ниже код работает, но через несколько часов браузер зависает, и консоль показывает эту ошибку:
ОШИБКА RangeError: превышен максимальный размер стека вызовов
togglePlay(): void {
this.isAnimationPlaying = !this.isAnimationPlaying;
if (this.isAnimationPlaying) {
this.setIndex();
} else {
clearTimeout();
}
}
setIndex() {
this.selectedIndex = (this.selectedIndex + 1) % this.matTabLength;
this.changeDetectorRef.detectChanges();
if (this.isAnimationPlaying) {
setTimeout(this.setIndex.bind(this), this.transitionSpeed);
} else {
clearTimeout();
}
}
Я попытался передать transitionSpeed в методе setTimeout следующим образом:
setTimeout(this.setIndex, this.transitionSpeed, this.transitionSpeed);
setIndex(transitionSpeed: number, selectedIndex: number, matTabLength: number) {
this.selectedIndex = (selectedIndex + 1) %.matTabLength;
if (this.isAnimationPlaying) {
setTimeout(this.setIndex, transitionSpeed, selectedIndex, matTabLength);
} else {
clearTimeout();
}
}
Но если метод вызывается второй раз, this.transitionSpeed имеет значение null.
Любая помощь высоко ценится
РЕДАКТИРОВАТЬ:
Изменил код на этот, но через несколько часов все еще появляется та же ошибка:
togglePlay(): void {
this.isAnimationPlaying = !this.isAnimationPlaying;
if (this.isAnimationPlaying) {
this.setIndex();
} else {
clearTimeout(this.timerId);
}
}
setIndex() {
this.selectedIndex = (this.selectedIndex + 1) % this.matTabLength;
this.changeDetectorRef.detectChanges();
if (this.isAnimationPlaying) {
clearTimeout(this.timerId);
this.timerId = setTimeout(this.setIndex.bind(this), this.transitionSpeed);
} else {
clearTimeout(this.timerId);
}
}
EDIT2: при изменении вкладки вызывается событие TabChange. Код:
tabChanged(event) {
this.themeClassesToRemove = Array.from(this.overlayContainer.getContainerElement().classList).filter((item: string) => item.includes('-template'));
if (Array.from(this.overlayContainer.getContainerElement().classList).filter((item: string) => item.includes('-template')).length) {
this.overlayContainer.getContainerElement().classList.remove(...this.themeClassesToRemove);
}
const label = event.tab.textLabel;
if (label.toLocaleLowerCase() === '1') {
this.templateService.default_template = this.templateService.grey_template;
} else if (label.toLocaleLowerCase() === '2') {
this.templateService.default_template = this.templateService.green_template;
} else if (label.toLocaleLowerCase() === '3') {
this.templateService.default_template = this.templateService.red_template;
} else {
this.templateService.default_template = this.templateService.blue_template;
}
this.overlayContainer.getContainerElement().classList.add(this.templateService.default_template);
window.dispatchEvent(new Event('resize'));
}
Это единственный метод, который вызывается после тайм-аута. Согласно этому сообщению, должен существовать метод рециркуляции, который вызывается все время. .