1

角度のあるマテリアル タブの変更が一定の時間間隔の後に発生するメソッドを実装しようとしています。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();
    }
}

ただし、メソッドが 2 回目に呼び出されると、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'));
    }

これは、タイムアウトのほかに呼び出される唯一のメソッドです。この投稿によると、常に呼び出される再帰的なメソッドが必要です。

4

1 に答える 1