fix(algorithms): render sliders only after first browser render
ngx-slider throws during prerender (no layout APIs on the server). Its ngOnDestroy then calls disconnect() on null, so about 1 in 10 prerender builds failed. Gate fractal and pendulum sliders on a signal set by afterNextRender.
This commit is contained in:
1 parent
82228e9141
commit
1cff9e6eb2
4 files changed
+24
-2
No files matched your search
@@ -31,7 +31,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="display: flex; align-items: center; gap: 10px;">
|
<div style="display: flex; align-items: center; gap: 10px;">
|
||||||
<mat-icon>zoom_out</mat-icon>
|
<mat-icon>zoom_out</mat-icon>
|
||||||
|
@if (sliderReady()) {
|
||||||
<ngx-slider [(value)]="sliderValue" [options]="options" (valueChange)="onSliderChange($event)" ></ngx-slider>
|
<ngx-slider [(value)]="sliderValue" [options]="options" (valueChange)="onSliderChange($event)" ></ngx-slider>
|
||||||
|
} @else {
|
||||||
|
<div class="grow h-[60px]"></div>
|
||||||
|
}
|
||||||
<mat-icon>zoom_in</mat-icon>
|
<mat-icon>zoom_in</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Component, OnInit, signal} from '@angular/core';
|
import {afterNextRender, Component, OnInit, signal} from '@angular/core';
|
||||||
import {Information} from '../information/information';
|
import {Information} from '../information/information';
|
||||||
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';
|
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';
|
||||||
import {TranslatePipe} from '@ngx-translate/core';
|
import {TranslatePipe} from '@ngx-translate/core';
|
||||||
@@ -39,6 +39,13 @@ import {clampZoom, initialView, iterationsForZoom, zoomAroundPoint} from './frac
|
|||||||
styleUrl: './fractal.component.scss',
|
styleUrl: './fractal.component.scss',
|
||||||
})
|
})
|
||||||
export class FractalComponent implements OnInit {
|
export class FractalComponent implements OnInit {
|
||||||
|
// ngx-slider throws on the server (no layout APIs), so render it in the browser only
|
||||||
|
readonly sliderReady = signal(false);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
afterNextRender(() => this.sliderReady.set(true));
|
||||||
|
}
|
||||||
|
|
||||||
algoInformation: AlgorithmInformation = {
|
algoInformation: AlgorithmInformation = {
|
||||||
title: 'FRACTAL.EXPLANATION.TITLE',
|
title: 'FRACTAL.EXPLANATION.TITLE',
|
||||||
entries: [
|
entries: [
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<app-information [algorithmInformation]="algoInformation"/>
|
<app-information [algorithmInformation]="algoInformation"/>
|
||||||
<div class="flex flex-col mb-4">
|
<div class="flex flex-col mb-4">
|
||||||
|
@if (sliderReady()) {
|
||||||
<div class="grid grid-cols-2 tablet:grid-cols-1 tablet:gap-4 mb-6">
|
<div class="grid grid-cols-2 tablet:grid-cols-1 tablet:gap-4 mb-6">
|
||||||
<div class="flex items-center gap-4 mr-4">
|
<div class="flex items-center gap-4 mr-4">
|
||||||
<p class="w-[100px] shrink-0 m-0 text-sm">{{ 'PENDULUM.TRAIL_DECAY_TIME' | translate }}</p>
|
<p class="w-[100px] shrink-0 m-0 text-sm">{{ 'PENDULUM.TRAIL_DECAY_TIME' | translate }}</p>
|
||||||
@@ -38,6 +39,9 @@
|
|||||||
<ngx-slider class="grow" [(value)]="damping" [options]="dampingOptions" ></ngx-slider>
|
<ngx-slider class="grow" [(value)]="damping" [options]="dampingOptions" ></ngx-slider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
} @else {
|
||||||
|
<div class="mb-6 h-[200px]"></div>
|
||||||
|
}
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-3 mb-4">
|
<div class="flex flex-wrap gap-3 mb-4">
|
||||||
<button mat-raised-button color="primary" (click)="pushPendulum(true)">
|
<button mat-raised-button color="primary" (click)="pushPendulum(true)">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Component, signal} from '@angular/core';
|
import {afterNextRender, Component, signal} from '@angular/core';
|
||||||
import {BabylonCanvas, RenderConfig, SceneEventData} from '../../../shared/components/render-canvas/babylon-canvas.component';
|
import {BabylonCanvas, RenderConfig, SceneEventData} from '../../../shared/components/render-canvas/babylon-canvas.component';
|
||||||
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';
|
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';
|
||||||
|
|
||||||
@@ -33,6 +33,13 @@ import {PendulumCpuStrategy} from './strategies/pendulum-cpu.strategy';
|
|||||||
})
|
})
|
||||||
class PendulumComponent {
|
class PendulumComponent {
|
||||||
|
|
||||||
|
// ngx-slider throws on the server (no layout APIs), so render it in the browser only
|
||||||
|
readonly sliderReady = signal(false);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
afterNextRender(() => this.sliderReady.set(true));
|
||||||
|
}
|
||||||
|
|
||||||
algoInformation: AlgorithmInformation = {
|
algoInformation: AlgorithmInformation = {
|
||||||
title: 'PENDULUM.EXPLANATION.TITLE',
|
title: 'PENDULUM.EXPLANATION.TITLE',
|
||||||
entries: [
|
entries: [
|
||||||
|
|||||||
Reference in new issue
Block a user