Skip to content

Commit 1702a51

Browse files
committed
fix: ensure cd is ran on route change if routed scene is used
1 parent ab66f5c commit 1702a51

File tree

8 files changed

+111
-47
lines changed

8 files changed

+111
-47
lines changed

apps/example/src/app/app.component.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component } from '@angular/core';
2-
import { RouterLink, RouterLinkActive } from '@angular/router';
3-
import { extend, NgtCanvas, NgtRoutedScene } from 'angular-three';
2+
import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
3+
import { extend } from 'angular-three';
44
import * as THREE from 'three';
55

66
extend(THREE);
@@ -11,15 +11,17 @@ extend(THREE);
1111
template: `
1212
<ul>
1313
<li>
14-
<a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Red</a>
14+
<a routerLink="/routed" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Red</a>
1515
</li>
1616
<li>
17-
<a routerLink="/blue" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Blue</a>
17+
<a routerLink="/routed/blue" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
18+
Blue
19+
</a>
1820
</li>
1921
</ul>
20-
<ngt-canvas [sceneGraph]="scene" />
22+
<router-outlet />
2123
`,
22-
imports: [NgtCanvas, RouterLink, RouterLinkActive],
24+
imports: [RouterOutlet, RouterLink, RouterLinkActive],
2325
styles: [
2426
`
2527
ul {
@@ -40,6 +42,4 @@ extend(THREE);
4042
`,
4143
],
4244
})
43-
export class AppComponent {
44-
readonly scene = NgtRoutedScene;
45-
}
45+
export class AppComponent {}

apps/example/src/app/blue-scene.component.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, inject, ViewChild } from '@angular/core';
2+
import { injectBeforeRender, NgtStore } from 'angular-three';
3+
4+
@Component({
5+
standalone: true,
6+
template: `
7+
<ngt-spot-light [position]="5" />
8+
<ngt-point-light [position]="-5" />
9+
10+
<ngt-mesh #cube>
11+
<ngt-icosahedron-geometry />
12+
<ngt-mesh-standard-material color="blue" />
13+
</ngt-mesh>
14+
`,
15+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
16+
})
17+
export default class BlueScene {
18+
@ViewChild('cube', { static: true }) cube!: ElementRef<THREE.Mesh>;
19+
20+
readonly store = inject(NgtStore);
21+
22+
constructor() {
23+
injectBeforeRender(({ clock }) => {
24+
this.cube.nativeElement.rotation.x = clock.elapsedTime;
25+
this.cube.nativeElement.rotation.y = clock.elapsedTime;
26+
});
27+
console.log(this.store.get('scene'));
28+
}
29+
30+
ngOnDestroy() {
31+
console.log('blue destroyed');
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
1-
import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, ViewChild } from '@angular/core';
2-
import { injectBeforeRender } from 'angular-three';
1+
import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, inject, ViewChild } from '@angular/core';
2+
import { injectBeforeRender, NgtStore } from 'angular-three';
33

44
@Component({
55
standalone: true,
66
template: `
7+
<ngt-point-light [position]="5" />
8+
<ngt-spot-light [position]="-5" />
9+
710
<ngt-mesh #cube>
811
<ngt-box-geometry />
9-
<ngt-mesh-basic-material color="red" />
12+
<ngt-mesh-standard-material color="red" />
1013
</ngt-mesh>
1114
`,
1215
schemas: [CUSTOM_ELEMENTS_SCHEMA],
1316
})
1417
export default class RedScene {
1518
@ViewChild('cube', { static: true }) cube!: ElementRef<THREE.Mesh>;
1619

20+
readonly store = inject(NgtStore);
21+
1722
constructor() {
1823
injectBeforeRender(({ clock }) => {
1924
this.cube.nativeElement.rotation.x = clock.elapsedTime;
2025
this.cube.nativeElement.rotation.y = clock.elapsedTime;
2126
});
27+
console.log(this.store.get('scene'));
28+
}
29+
30+
ngOnDestroy() {
31+
console.log('red destroyed');
2232
}
2333
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Component } from '@angular/core';
2+
import { NgtCanvas, NgtRoutedScene } from 'angular-three';
3+
4+
@Component({
5+
standalone: true,
6+
template: ` <ngt-canvas [sceneGraph]="scene" /> `,
7+
imports: [NgtCanvas],
8+
})
9+
export default class Scene {
10+
readonly scene = NgtRoutedScene;
11+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Routes } from '@angular/router';
2+
3+
const routes: Routes = [
4+
{
5+
path: '',
6+
loadComponent: () => import('./red-scene.component'),
7+
},
8+
{
9+
path: 'blue',
10+
loadComponent: () => import('./blue-scene.component'),
11+
},
12+
];
13+
14+
export default routes;

apps/example/src/main.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import { bootstrapApplication } from '@angular/platform-browser';
2-
import { provideRouter } from '@angular/router';
2+
import { provideRouter, withDebugTracing } from '@angular/router';
33
import { AppComponent } from './app/app.component';
44

55
bootstrapApplication(AppComponent, {
66
providers: [
7-
provideRouter([
8-
{
9-
path: '',
10-
loadComponent: () => import('./app/red-scene.component'),
11-
},
12-
{
13-
path: 'blue',
14-
loadComponent: () => import('./app/blue-scene.component'),
15-
},
16-
]),
7+
provideRouter(
8+
[
9+
{
10+
path: '',
11+
redirectTo: 'routed',
12+
pathMatch: 'full',
13+
},
14+
{
15+
path: 'routed',
16+
loadComponent: () => import('./app/scene/scene.component'),
17+
loadChildren: () => import('./app/scene/scene.routes'),
18+
},
19+
],
20+
withDebugTracing()
21+
),
1722
],
1823
}).catch((err) => console.error(err));

libs/angular-three/src/lib/routed-scene.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Component } from '@angular/core';
2-
import { RouterOutlet } from '@angular/router';
2+
import { ActivationEnd, Router, RouterOutlet } from '@angular/router';
3+
import { filter, takeUntil } from 'rxjs';
4+
import { injectNgtDestroy } from './di/destroy';
35

46
@Component({
57
standalone: true,
@@ -9,4 +11,16 @@ import { RouterOutlet } from '@angular/router';
911
})
1012
export class NgtRoutedScene {
1113
static isRoutedScene = true;
14+
15+
constructor(router: Router) {
16+
const { destroy$, cdr } = injectNgtDestroy();
17+
router.events
18+
.pipe(
19+
filter((event) => event instanceof ActivationEnd),
20+
takeUntil(destroy$)
21+
)
22+
.subscribe(() => {
23+
cdr.detectChanges();
24+
});
25+
}
1226
}

0 commit comments

Comments
 (0)