Skip to content

Commit f9c7838

Browse files
committed
translate: translations for signals guide
Fixes #16
1 parent 3b55bfc commit f9c7838

File tree

11 files changed

+683
-778
lines changed

11 files changed

+683
-778
lines changed

adev-es/src/app/sub-navigation-data.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
7373
],
7474
},
7575
{
76-
label: 'In-depth Guides',
76+
label: 'Guías Detalladas',
7777
children: [
7878
{
7979
label: 'Componentes',
@@ -339,29 +339,19 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
339339
label: 'Signals',
340340
children: [
341341
{
342-
label: 'Overview',
342+
label: 'Visión general',
343343
path: 'guide/signals',
344344
contentPath: 'guide/signals/overview',
345345
},
346346
{
347-
label: 'RxJS Interop',
348-
path: 'guide/signals/rxjs-interop',
349-
contentPath: 'guide/signals/rxjs-interop',
350-
},
351-
{
352-
label: 'Inputs as signals',
353-
path: 'guide/signals/inputs',
354-
contentPath: 'guide/signals/inputs',
355-
},
356-
{
357-
label: 'Model inputs',
358-
path: 'guide/signals/model',
359-
contentPath: 'guide/signals/model',
347+
label: 'Estado dependiente con linkedSignal',
348+
path: 'guide/signals/linked-signal',
349+
contentPath: 'guide/signals/linked-signal',
360350
},
361351
{
362-
label: 'Queries as signals',
363-
path: 'guide/signals/queries',
364-
contentPath: 'guide/signals/queries',
352+
label: 'Reactividad asíncrona con resource',
353+
path: 'guide/signals/resource',
354+
contentPath: 'guide/signals/resource',
365355
},
366356
],
367357
},

adev-es/src/content/guide/signals/inputs.md

Lines changed: 0 additions & 147 deletions
This file was deleted.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Dependent state with `linkedSignal`
2+
3+
You can use the `signal` function to hold some state in your Angular code. Sometimes, this state depends on some _other_ state. For example, imagine a component that lets the user select a shipping method for an order:
4+
5+
```typescript
6+
@Component({/* ... */})
7+
export class ShippingMethodPicker {
8+
shippingOptions: Signal<ShippingMethod[]> = getShippingOptions();
9+
10+
// Select the first shipping option by default.
11+
selectedOption = signal(this.shippingOptions()[0]);
12+
13+
changeShipping(newOptionIndex: number) {
14+
this.selectedOption.set(this.shippingOptions()[newOptionIndex]);
15+
}
16+
}
17+
```
18+
19+
In this example, the `selectedOption` defaults to the first option, but changes if the user selects another option. But `shippingOptions` is a signal— its value may change! If `shippingOptions` changes, `selectedOption` may contain a value that is no longer a valid option.
20+
21+
**The `linkedSignal` function lets you create a signal to hold some state that is intrinsically _linked_ to some other state.** Revisiting the example above, `linkedSignal` can replace `signal`:
22+
23+
```typescript
24+
@Component({/* ... */})
25+
export class ShippingMethodPicker {
26+
shippingOptions: Signal<ShippingMethod[]> = getShippingOptions();
27+
28+
// Initialize selectedOption to the first shipping option.
29+
selectedOption = linkedSignal(() => this.shippingOptions()[0]);
30+
31+
changeShipping(index: number) {
32+
this.selectedOption.set(this.shippingOptions()[index]);
33+
}
34+
}
35+
```
36+
37+
`linkedSignal` works similarly to `signal` with one key difference— instead of passing a default value, you pass a _computation function_, just like `computed`. When the value of the computation changes, the value of the `linkedSignal` changes to the computation result. This helps ensure that the `linkedSignal` always has a valid value.
38+
39+
The following example shows how the value of a `linkedSignal` can change based on its linked state:
40+
41+
```typescript
42+
const shippingOptions = signal(['Ground', 'Air', 'Sea']);
43+
const selectedOption = linkedSignal(() => shippingOptions()[0]);
44+
console.log(selectedOption()); // 'Ground'
45+
46+
selectedOption.set(shippingOptions()[2]);
47+
console.log(selectedOption()); // 'Sea'
48+
49+
shippingOptions.set(['Email', 'Will Call', 'Postal service']);
50+
console.log(selectedOption()); // 'Email'
51+
```
52+
53+
## Accounting for previous state
54+
55+
In some cases, the computation for a `linkedSignal` needs to account for the previous value of the `linkedSignal`.
56+
57+
In the example above, `selectedOption` always updates back to the first option when `shippingOptions` changes. You may, however, want to preserve the user's selection if their selected option is still somewhere in the list. To accomplish this, you can create a `linkedSignal` with a separate _source_ and _computation_:
58+
59+
```typescript
60+
interface ShippingMethod {
61+
id: number;
62+
name: string;
63+
}
64+
65+
@Component({/* ... */})
66+
export class ShippingMethodPicker {
67+
constructor() {
68+
this.changeShipping(2);
69+
this.changeShippingOptions();
70+
console.log(this.selectedOption()); // {"id":2,"name":"Postal Service"}
71+
}
72+
73+
shippingOptions = signal<ShippingMethod[]>([
74+
{ id: 0, name: 'Ground' },
75+
{ id: 1, name: 'Air' },
76+
{ id: 2, name: 'Sea' },
77+
]);
78+
79+
selectedOption = linkedSignal<ShippingMethod[], ShippingMethod>({
80+
// `selectedOption` is set to the `computation` result whenever this `source` changes.
81+
source: this.shippingOptions,
82+
computation: (newOptions, previous) => {
83+
// If the newOptions contain the previously selected option, preserve that selection.
84+
// Otherwise, default to the first option.
85+
return (
86+
newOptions.find((opt) => opt.id === previous?.value.id) ?? newOptions[0]
87+
);
88+
},
89+
});
90+
91+
changeShipping(index: number) {
92+
this.selectedOption.set(this.shippingOptions()[index]);
93+
}
94+
95+
changeShippingOptions() {
96+
this.shippingOptions.set([
97+
{ id: 0, name: 'Email' },
98+
{ id: 1, name: 'Sea' },
99+
{ id: 2, name: 'Postal Service' },
100+
]);
101+
}
102+
}
103+
```
104+
105+
When you create a `linkedSignal`, you can pass an object with separate `source` and `computation` properties instead of providing just a computation.
106+
107+
The `source` can be any signal, such as a `computed` or component `input`. When the value of `source` changes, `linkedSignal` updates its value to the result of the provided `computation`.
108+
109+
The `computation` is a function that receives the new value of `source` and a `previous` object. The `previous` object has two properties— `previous.source` is the previous value of `source`, and `previous.value` is the previous result of the `computation`. You can use these previous values to decide the new result of the computation.
110+
111+
HELPFUL: When using the `previous` parameter, it is necessary to provide the generic type arguments of `linkedSignal` explicitly. The first generic type corresponds with the type of `source` and the second generic type determines the output type of `computation`.
112+
113+
## Custom equality comparison
114+
115+
`linkedSignal`, as any other signal, can be configured with a custom equality function. This function is used by downstream dependencies to determine if that value of the `linkedSignal` (result of a computation) changed:
116+
117+
```typescript
118+
const activeUser = signal({id: 123, name: 'Morgan', isAdmin: true});
119+
120+
const activeUserEditCopy = linkedSignal(() => activeUser(), {
121+
// Consider the user as the same if it's the same `id`.
122+
equal: (a, b) => a.id === b.id,
123+
});
124+
125+
// Or, if separating `source` and `computation`
126+
const activeUserEditCopy = linkedSignal({
127+
source: activeUser,
128+
computation: user => user,
129+
equal: (a, b) => a.id === b.id,
130+
});
131+
```

0 commit comments

Comments
 (0)