|
| 1 | +--- |
| 2 | +title: Migrate to V2 |
| 3 | +description: Details about Angular Three v2 migration |
| 4 | +--- |
| 5 | + |
| 6 | +As mentioned in the [v2 release blog post](https://angularthree.org/blog/v2), Angular Three v2 is a major release with a substantial change in the migration strategy. It aims to address the limitations of the previous version, resulting in numerous breaking changes. Some of these changes are subtle and may not be immediately apparent. |
| 7 | + |
| 8 | +While it is mentioned that migration path cannot be provided in details, I will try my best to provide a non-exhaustive overview of the changes and how to migrate. |
| 9 | + |
| 10 | +## Custom Renderer |
| 11 | + |
| 12 | +While many have noticed the custom renderer usage from the previous version of the documentation, it has been brought to my attention that some folks are still using `angular-three` before the custom renderer. |
| 13 | + |
| 14 | +Here's a quick summary: |
| 15 | + |
| 16 | +- Use `NgtCanvas` with `sceneGraph` input instead of putting your scene graph as content child of `ngt-canvas` |
| 17 | + |
| 18 | +```diff lang="angular-html" |
| 19 | +- <ngt-canvas> |
| 20 | +- <ngt-mesh> |
| 21 | +- <ngt-box-geometry /> |
| 22 | +- <ngt-mesh-basic-material /> |
| 23 | +- </ngt-mesh> |
| 24 | +- </ngt-canvas> |
| 25 | + |
| 26 | ++ <ngt-canvas [sceneGraph]="sceneGraph" /> |
| 27 | +``` |
| 28 | + |
| 29 | +- `sceneGraph` is a reference to a `Component` that renders your entire scene graph. |
| 30 | + |
| 31 | +```angular-ts |
| 32 | +@Component({ |
| 33 | + standalone: true, |
| 34 | + template: ` |
| 35 | + <ngt-mesh> |
| 36 | + <ngt-box-geometry /> |
| 37 | + <ngt-mesh-basic-material /> |
| 38 | + </ngt-mesh> |
| 39 | + `, |
| 40 | + schemas: [CUSTOM_ELEMENTS_SCHEMA], |
| 41 | +}) |
| 42 | +export class SceneGraph {} |
| 43 | +
|
| 44 | +@Component({ |
| 45 | + template: ` |
| 46 | + <ngt-canvas [sceneGraph]="sceneGraph" /> |
| 47 | + `, |
| 48 | + imports: [NgtCanvas], |
| 49 | +}) |
| 50 | +export class App { |
| 51 | + protected sceneGraph = SceneGraph; |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +- `CUSTOM_ELEMENTS_SCHEMA` is required. Please refer to the [Custom Renderer](/core/api/custom-renderer) documentation for more information. |
| 56 | +- All `ngt-*` elements do not have an importable symbol (they're not `Directive` nor `Component`). |
| 57 | + |
| 58 | +## Scene Graph Inputs |
| 59 | + |
| 60 | +Since the `sceneGraph` reference is passed in as an input and the `NgtCanvas` will render the scene graph with the custom renderer, there is no straightforward way to pass Inputs to the scene graph component itself. |
| 61 | + |
| 62 | +Use a shared service or a shared `Signal` to pass data from outside to the Scene Graph component. |
| 63 | + |
| 64 | +```angular-ts |
| 65 | +const count = signal(0); |
| 66 | +
|
| 67 | +@Component({ |
| 68 | + template: `<ngt-mesh (click)="onClick()"></ngt-mesh>`, |
| 69 | +}) |
| 70 | +export class SceneGraph { |
| 71 | + onClick() { |
| 72 | + count.update((prev) => prev + 1); |
| 73 | + } |
| 74 | +} |
| 75 | +
|
| 76 | +@Component({ |
| 77 | + template: ` |
| 78 | + <ngt-canvas [sceneGraph]="sceneGraph" /> |
| 79 | + <p>Current count: {{ count() }}</p> |
| 80 | + `, |
| 81 | +}) |
| 82 | +export class App { |
| 83 | + protected sceneGraph = SceneGraph; |
| 84 | + protected count = count; |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +## Custom Inject Functions |
| 89 | + |
| 90 | +All of `injectNgt*` functions have been renamed to just `inject*` instead. |
| 91 | + |
| 92 | +```diff |
| 93 | +- injectNgtLoader(); |
| 94 | ++ injectLoader(); |
| 95 | + |
| 96 | +- injectNgtStore(); |
| 97 | ++ injectStore(); |
| 98 | +``` |
| 99 | + |
| 100 | +## `NgtSignalStore` |
| 101 | + |
| 102 | +While not common, consumers can use `signalStore()` to create a `NgtSignalStore`. The purpose of `NgtSignalStore` is a minimal store implementation that `angular-three` uses internally. |
| 103 | + |
| 104 | +### Methods |
| 105 | + |
| 106 | +1. `select(...keys, options?)`: Retrieves a Signal of a part of the state. |
| 107 | + - Can select nested properties using multiple arguments |
| 108 | + - Returns `Signal<T>` where T is the type of the selected state |
| 109 | + |
| 110 | +2. `get(...keys)`: Retrieves the current value of a part of the state. |
| 111 | + - Can access nested properties using multiple arguments |
| 112 | + - Returns the value directly, not wrapped in a Signal |
| 113 | + |
| 114 | +3. `update(stateOrUpdater)`: Updates the state. |
| 115 | + - Accepts a partial state object or an updater function |
| 116 | + - Updater function receives the previous state and returns a partial state |
| 117 | + |
| 118 | +4. `state`: A Signal representing the entire state. |
| 119 | + - Equivalent to `select()` without arguments |
| 120 | + |
| 121 | +5. `snapshot`: A getter that returns the current state value. |
| 122 | + - Equivalent to `get()` without arguments |
| 123 | + |
| 124 | +### Creation |
| 125 | + |
| 126 | +Created using the `signalStore` function: |
| 127 | + |
| 128 | +```typescript |
| 129 | +signalStore<State>( |
| 130 | + initialState?: Partial<State> | ((api: Pick<NgtSignalStore<State>, 'get' | 'update' | 'select'>) => Partial<State>), |
| 131 | + options?: CreateSignalOptions<State> |
| 132 | +): NgtSignalStore<State> |
| 133 | +``` |
| 134 | + |
| 135 | +## Signals everywhere |
| 136 | + |
| 137 | +All public APIs return `Signal` instead of `Observable`. Consumers can try to use `toObservable()` to convert it to an `Observable` if needed to minimize the changes. |
| 138 | + |
| 139 | +## `NgtRef` |
| 140 | + |
| 141 | +`NgtRef` has been removed. Use Signal Query API instead: `viewChild`, `viewChildren`, `contentChild`, and `contentChildren`. |
| 142 | + |
| 143 | +## Missing components from `angular-three-soba` |
| 144 | + |
| 145 | +During the work on v2, most components are rewritten from scratch to accommodate the Signal APIs. Hence, there are some components that are missing from previous version of `angular-three-soba`. |
| 146 | + |
| 147 | +If you find missing components, please open an issue on Github. |
0 commit comments