|
1 | 1 | # Linked State
|
2 | 2 |
|
3 |
| -The `withLinkedState` feature enables the creation of state slices that depend on other parts of the state. It supports both implicit and explicit linking. |
4 |
| - |
5 |
| -In the context of the SignalStore, `withLinkedState()` serves as the equivalent to Angular's `linkedSignal()`. |
6 |
| - |
7 |
| -Linked state can be added to the store using the `withLinkedState()` feature. This feature accepts a factory function as an input argument, which is executed within the injection context. The factory should return a dictionary containing: |
8 |
| - |
9 |
| -- Functions that return values, which the SignalStore wraps automatically into a `linkedSignal()`, or |
10 |
| -- `WritableSignal`, which the user can create with `linkedSignal()`. |
| 3 | +The `withLinkedState` feature enables the creation of state slices that depend on other signals. |
| 4 | +This feature accepts a factory function as an input argument, which is executed within the injection context. |
| 5 | +The factory should return a dictionary containing linked state slices, defined as either computation functions or `WritableSignal` instances. |
| 6 | +These linked state slices become an integral part of the SignalStore's state and are treated the same as regular state slices - `DeepSignal`s are created for each of them, and they can be updated using `patchState`. |
11 | 7 |
|
12 | 8 | ## Implicit Linking
|
13 | 9 |
|
14 |
| -The following example shows the implicit notation, where a function returns a value. That function is wrapped into a `linkedSignal()`, which means it is tracked, and if one of the tracked Signals changes, the function is re-executed synchronously. |
| 10 | +When a computation function is provided, the SignalStore wraps it in a `linkedSignal()`. |
| 11 | +As a result, the linked state slice is updated automatically whenever any of its dependent signals change. |
15 | 12 |
|
16 |
| -<ngrx-code-example header="options-store.ts"> |
| 13 | +<code-tabs linenums="true"> |
| 14 | +<code-pane header="options-store.ts"> |
17 | 15 |
|
18 | 16 | ```ts
|
19 |
| -import { |
20 |
| - signalStore, |
21 |
| - withLinkedState, |
22 |
| - withState, |
23 |
| -} from '@ngrx/signals'; |
| 17 | +import { patchState, signalStore, withLinkedState, withState } from '@ngrx/signals'; |
24 | 18 |
|
25 | 19 | export const OptionsStore = signalStore(
|
26 |
| - withState({ options: [1, 2, 3] }), |
27 |
| - withLinkedState(({ options }) => ({ |
28 |
| - selectedOption: () => options()[0] ?? undefined, |
29 |
| - })) |
| 20 | + withState({ options: [1, 2, 3] }), |
| 21 | + withLinkedState(({ options }) => ({ |
| 22 | + // 👇 Defining a linked state slice. |
| 23 | + selectedOption: () => options()[0] ?? undefined, |
| 24 | + })), |
| 25 | + withMethods((store) => ({ |
| 26 | + setOptions(options: number[]): void { |
| 27 | + patchState(store, { options }); |
| 28 | + }, |
| 29 | + setSelectedOption(selectedOption: number): void { |
| 30 | + // 👇 Updating a linked state slice. |
| 31 | + patchState(store, { selectedOption }); |
| 32 | + }, |
| 33 | + }), |
30 | 34 | );
|
31 | 35 | ```
|
32 | 36 |
|
33 |
| -</ngrx-code-example> |
| 37 | +</code-pane> |
| 38 | +
|
| 39 | +<code-pane header="option-list.ts"> |
| 40 | +
|
| 41 | +```ts |
| 42 | +@Component({ |
| 43 | + // ... other metadata |
| 44 | + providers: [OptionsStore], |
| 45 | +}) |
| 46 | +export class OptionList { |
| 47 | + readonly store = inject(OptionsStore); |
| 48 | + |
| 49 | + constructor() { |
| 50 | + console.log(this.store.selectedOption()); // logs: 1 |
| 51 | + |
| 52 | + this.store.setSelectedOption(2); |
| 53 | + console.log(this.store.selectedOption()); // logs: 2 |
| 54 | + |
| 55 | + this.store.setOptions([4, 5, 6]); |
| 56 | + console.log(this.store.selectedOption()); // logs: 4 |
| 57 | + } |
| 58 | +} |
| 59 | +``` |
| 60 | +
|
| 61 | +</code-pane> |
| 62 | +</code-tabs> |
34 | 63 |
|
35 | 64 | ## Explicit Linking
|
36 | 65 |
|
37 |
| -The explicit notation requires users to execute `linkedSignal()` manually; however, it offers the advantage of using the more powerful version of `linkedSignal()`, which includes the `source` and `computation` options. |
| 66 | +The `withLinkedState` feature also supports providing `WritableSignal` instances as linked state slices. |
| 67 | +This can include signals created using `linkedSignal()` with `source` and `computation` options, as well as any other `WritableSignal` instances. |
| 68 | +In both cases, the SignalStore and the original signal remain fully synchronized - updating one immediately reflects in the other. |
38 | 69 |
|
39 | 70 | <ngrx-code-example header="options-store.ts">
|
40 | 71 |
|
|
0 commit comments