Angular 22
Ejercicios de Angular sobre Signals
13 ejercicios de Signals en Angular; aquí tienes 12, empezando por los más básicos. Piensa la respuesta antes de abrirla: la explicación dice por qué las demás opciones fallan.
1 · Elige la respuesta · nivel 1
¿Qué imprime este código?
const count = signal(0);count.set(5);console.log(count());- A5
- B0
- CSignal { value: 5 }
- Dundefined
Ver la respuesta
Respuesta: A. 5
Un signal se lee llamándolo como función. set() reemplaza el valor, así que count() devuelve 5.
2 · Elige la respuesta · nivel 1
En el componente hay count = signal(5). ¿Cómo se muestra su valor en la plantilla?
- A{{ count() }}
- B{{ count }}
- C{{ count.value }}
- D{{ signal(count) }}
Ver la respuesta
Respuesta: A. {{ count() }}
Un signal se lee llamándolo como una función: count(). Sin paréntesis mostrarías la función, no el número.
3 · Encuentra el fallo · nivel 1
El botón no muestra el número del contador. ¿Qué línea tiene el fallo?
1@Component({2 selector: 'app-counter',3 template: `<button (click)="inc()">{{ count }}</button>`,4})5export class Counter {6 count = signal(0);7 inc() { this.count.update((n) => n + 1); }8}Ver la respuesta
El fallo está en la línea 3:
template: `<button (click)="inc()">{{ count }}</button>`,En la plantilla, un signal también se lee llamándolo: {{ count() }}. Sin paréntesis se interpola la función, no su valor.
4 · Encuentra el fallo · nivel 1
name es un signal y el nombre no se muestra bien. ¿Qué línea tiene el fallo?
1<header>2 <h1>Mi perfil</h1>3 <p>{{ name }}</p>4</header>Ver la respuesta
El fallo está en la línea 3:
<p>{{ name }}</p>Se arregla con<p>{{ name() }}</p>.Los signals se leen llamándolos: name(). Sin paréntesis la plantilla recibe el signal en sí, no su valor.
5 · Completa el hueco · nivel 1
Completa un contador con signals.
count = ___(0); increment() { this.count.___((n) => n + 1);}- signal
- update
- set
- computed
- mutate
- effect
Ver la respuesta
Respuesta: signal · update
count = signal(0); increment() { this.count.update((n) => n + 1);}signal() crea el estado con un valor inicial. update() calcula el valor nuevo a partir del anterior; set() lo reemplaza sin mirarlo. mutate() se eliminó hace varias versiones.
6 · Completa el hueco · nivel 1
Completa para crear un signal con valor inicial 0 y leerlo en la plantilla.
// En la claseclicks = ___(0); <!-- En la plantilla --><p>{{ clicks___ }}</p>- signal
- ()
- useState
- .value
Ver la respuesta
Respuesta: signal · ()
// En la claseclicks = signal(0); <!-- En la plantilla --><p>{{ clicks() }}</p>signal(0) crea un signal con valor inicial 0 y se lee llamándolo: clicks(). useState es de React.
7 · Elige la respuesta · nivel 2
¿Qué imprime este código?
const price = signal(10);const double = computed(() => price() * 2);price.set(100);console.log(double());- A200
- B20
- C10
- DError: computed es de solo lectura
Ver la respuesta
Respuesta: A. 200
computed guarda qué signals lee y se recalcula cuando alguno cambia. Tras price.set(100), double() vale 200.
8 · Elige la respuesta · nivel 2
¿Qué imprime este código?
const options = signal(['S', 'M', 'L']);const selected = linkedSignal(() => options()[0]); selected.set('L');options.set(['XS', 'S']);console.log(selected());- AXS
- BL
- CS
- DError: linkedSignal es de solo lectura
Ver la respuesta
Respuesta: A. XS
linkedSignal es un signal editable que se recalcula cuando cambia su origen. set('L') lo cambia a mano, pero al cambiar options vuelve a calcularse y toma el primero de la lista nueva.
9 · Elige la respuesta · nivel 2
¿Cuántas veces se imprime calculando?
const a = signal(1);const double = computed(() => { console.log('calculando'); return a() * 2;}); double();double();a.set(2);a.set(3);console.log(double());- A2
- B4
- C3
- D1
Ver la respuesta
Respuesta: A. 2
computed es perezoso y guarda el resultado. La primera lectura calcula y la segunda reutiliza. Los dos set solo lo marcan como desactualizado, y recalcula una vez, en la siguiente lectura.
10 · Elige la respuesta · nivel 2
¿Cuándo se ejecuta este effect?
constructor() { effect(() => { console.log('usuario:', this.user().name); });}- AUna vez al crearse el componente y de nuevo cuando cambia user
- BSolo cuando cambia user, nunca al crearse
- CEn cada ciclo de detección de cambios
- DSolo una vez, al crearse
Ver la respuesta
Respuesta: A. Una vez al crearse el componente y de nuevo cuando cambia user
Un effect se ejecuta al menos una vez y registra los signals que lee. Cuando alguno cambia, vuelve a ejecutarse. Si user cambia varias veces seguidas, Angular agrupa los cambios en una sola ejecución.
11 · Encuentra el fallo · nivel 2
Al añadir un producto, la plantilla no se actualiza. ¿Qué línea tiene el fallo?
1export class Cart {2 items = signal<string[]>([]);3 4 add(item: string) {5 this.items().push(item);6 }7}Ver la respuesta
El fallo está en la línea 5:
this.items().push(item);Mutar el array que devuelve el signal no le avisa de ningún cambio. Hay que crear un valor nuevo: this.items.update((list) => [...list, item]).
12 · Encuentra el fallo · nivel 2
El componente entra en un bucle infinito. ¿Qué línea lo provoca?
1export class Counter {2 count = signal(0);3 4 constructor() {5 effect(() => {6 this.count.set(this.count() + 1);7 });8 }9}Ver la respuesta
El fallo está en la línea 6:
this.count.set(this.count() + 1);El effect lee count y a la vez lo modifica, así que cada ejecución programa la siguiente. Para derivar un valor de otro, usa computed. Si de verdad hay que leer sin suscribirse, está untracked().