我正在尝试实现一种方法,在该方法中,在固定的时间间隔后会更改角度材质选项卡。我尝试在JavaScript中使用setInterval,但是它的工作原理不是很可靠(选项卡更改是随机发生的)。 下面发布的代码有效,但是几个小时后浏览器冻结,控制台显示此错误:
错误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();
}
}
我尝试在setTimeout方法中传递transitionSpeed,如下所示:
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'));
}
这是唯一的方法,在超时旁边被调用。根据此post,必须有一个一直被调用的递归方法。
答案 0 :(得分:0)
setTimeout
。返回计时器ID,然后您可以在clearTimeout
中使用该计时器ID清除它:
timerId = setTimeout(this.setIndex.bind(this), this.transitionSpeed);
clearTimeout(timerId);