diff --git a/adev-es/src/content/tutorials/signals/intro/README.en.md b/adev-es/src/content/tutorials/signals/intro/README.en.md
new file mode 100644
index 0000000..b9d8df8
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/intro/README.en.md
@@ -0,0 +1,13 @@
+# Learn Angular signals
+
+This interactive tutorial will teach you the fundamentals of Angular signals and how to use them to build reactive applications.
+
+## How to use this tutorial
+
+This tutorial assumes you understand Angular's core concepts. If you're new to Angular, read our [essentials guide](/essentials).
+
+Each step represents a concept in Angular signals. You can do one, or all of them.
+
+If you get stuck, click "Reveal answer" at the top.
+
+Alright, let's [get started](/tutorials/signals/1-creating-your-first-signal)!
diff --git a/adev-es/src/content/tutorials/signals/intro/README.md b/adev-es/src/content/tutorials/signals/intro/README.md
index b9d8df8..dc33dec 100644
--- a/adev-es/src/content/tutorials/signals/intro/README.md
+++ b/adev-es/src/content/tutorials/signals/intro/README.md
@@ -1,13 +1,13 @@
-# Learn Angular signals
+# Aprende sobre signals en Angular
-This interactive tutorial will teach you the fundamentals of Angular signals and how to use them to build reactive applications.
+Este tutorial interactivo te enseñará los fundamentos de los signals de Angular y cómo usarlos para construir aplicaciones reactivas.
-## How to use this tutorial
+## Cómo usar este tutorial
-This tutorial assumes you understand Angular's core concepts. If you're new to Angular, read our [essentials guide](/essentials).
+Este tutorial asume que entiendes los conceptos principales de Angular. Si eres nuevo en Angular, lee nuestra [guía esencial](/essentials).
-Each step represents a concept in Angular signals. You can do one, or all of them.
+Cada paso representa un concepto en los signals de Angular. Puedes hacer uno, o todos ellos.
-If you get stuck, click "Reveal answer" at the top.
+Si te quedas atascado, haz clic en "Reveal answer" (Mostrar respuesta) en la parte superior.
-Alright, let's [get started](/tutorials/signals/1-creating-your-first-signal)!
+Muy bien, ¡[comencemos](/tutorials/signals/1-creating-your-first-signal)!
diff --git a/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md b/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md
new file mode 100644
index 0000000..cd2cf93
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.en.md
@@ -0,0 +1,130 @@
+# Creating and updating your first signal
+
+Welcome to the Angular signals tutorial! [Signals](/essentials/signals) are Angular's reactive primitive that provide a way to manage state and automatically update your UI when that state changes.
+
+In this activity, you'll learn how to:
+
+- Create your first signal using the `signal()` function
+- Display its value in a template
+- Update the signal value using `set()` and `update()` methods
+
+Let's build an interactive user status system with signals!
+
+
+
+
+
+
+Import the `signal` function from `@angular/core` at the top of your component file.
+
+```ts
+import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
+```
+
+
+
+
+Add a `userStatus` signal to your component class that is initialized with a value of `'offline'`.
+
+```ts
+@Component({
+ /* Config omitted */
+})
+export class App {
+ userStatus = signal<'online' | 'offline'>('offline');
+}
+```
+
+
+
+
+Update the status indicator to display the current user status by:
+1. Binding the signal to the class attribute with `[class]="userStatus()"`
+2. Displaying the status text by replacing `???` with `{{ userStatus() }}`
+
+```html
+
+
+
+ Status: ???
+
+
+
+
+
+ Status: {{ userStatus() }}
+
+```
+
+Notice how we call the signal `userStatus()` with parentheses to read its value.
+
+
+
+Add methods to your component that change the user status using the `set()` method.
+
+```ts
+goOnline() {
+ this.userStatus.set('online');
+}
+
+goOffline() {
+ this.userStatus.set('offline');
+}
+```
+
+The `set()` method replaces the signal's value entirely with a new value.
+
+
+
+
+The buttons are already in the template. Now connect them to your methods by adding:
+1. Click handlers with `(click)`
+2. Disabled states with `[disabled]` when already in that status
+
+```html
+
+
+
+```
+
+
+
+
+Add a `toggleStatus()` method that switches between online and offline using the `update()` method.
+
+```ts
+toggleStatus() {
+ this.userStatus.update(current => current === 'online' ? 'offline' : 'online');
+}
+```
+
+The `update()` method takes a function that receives the current value and returns the new value. This is useful when you need to modify the existing value based on its current state.
+
+
+
+
+The toggle button is already in the template. Connect it to your `toggleStatus()` method:
+
+```html
+
+```
+
+
+
+
+
+Congratulations! You've created your first signal and learned how to update it using both `set()` and `update()` methods. The `signal()` function creates a reactive value that Angular tracks, and when you update it, your UI automatically reflects the changes.
+
+Next, you'll learn [how to derive state from signals using computed](/tutorials/signals/2-deriving-state-with-computed-signals)!
+
+
+
+You might notice `ChangeDetectionStrategy.OnPush` in the component decorator throughout this tutorial. This is a performance optimization for Angular components that use signals. For now, you can safely ignore it—just know it helps your app run faster when using signals! You can learn more in the [change detection strategies API docs](/api/core/ChangeDetectionStrategy).
+
+
diff --git a/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md b/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md
index cd2cf93..3136754 100644
--- a/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/1-creating-your-first-signal/README.md
@@ -1,21 +1,21 @@
-# Creating and updating your first signal
+# Creando y actualizando tu primer signal
-Welcome to the Angular signals tutorial! [Signals](/essentials/signals) are Angular's reactive primitive that provide a way to manage state and automatically update your UI when that state changes.
+¡Bienvenido al tutorial de signals de Angular! Los [signals](/essentials/signals) son la primitiva reactiva de Angular que proporciona una forma de gestionar estado y actualizar automáticamente tu UI cuando ese estado cambia.
-In this activity, you'll learn how to:
+En esta actividad, aprenderás cómo:
-- Create your first signal using the `signal()` function
-- Display its value in a template
-- Update the signal value using `set()` and `update()` methods
+- Crear tu primer signal usando la función `signal()`
+- Mostrar su valor en una plantilla
+- Actualizar el valor del signal usando los métodos `set()` y `update()`
-Let's build an interactive user status system with signals!
+¡Construyamos un sistema interactivo de estado de usuario con signals!
-
-Import the `signal` function from `@angular/core` at the top of your component file.
+
+Importa la función `signal` desde `@angular/core` al inicio de tu archivo de componente.
```ts
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
@@ -23,12 +23,12 @@ import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
-
-Add a `userStatus` signal to your component class that is initialized with a value of `'offline'`.
+
+Agrega un signal `userStatus` a tu clase de componente que se inicialice con un valor de `'offline'`.
```ts
@Component({
- /* Config omitted */
+ /* Config omitida */
})
export class App {
userStatus = signal<'online' | 'offline'>('offline');
@@ -37,30 +37,30 @@ export class App {
-
-Update the status indicator to display the current user status by:
-1. Binding the signal to the class attribute with `[class]="userStatus()"`
-2. Displaying the status text by replacing `???` with `{{ userStatus() }}`
+
+Actualiza el indicador de estado para mostrar el estado actual del usuario:
+1. Vinculando el signal al atributo class con `[class]="userStatus()"`
+2. Mostrando el texto de estado reemplazando `???` con `{{ userStatus() }}`
```html
-
+
Status: ???
-
+
Status: {{ userStatus() }}
```
-Notice how we call the signal `userStatus()` with parentheses to read its value.
+Observa cómo llamamos al signal `userStatus()` con paréntesis para leer su valor.
-
-Add methods to your component that change the user status using the `set()` method.
+
+Agrega métodos a tu componente que cambien el estado del usuario usando el método `set()`.
```ts
goOnline() {
@@ -72,17 +72,17 @@ goOffline() {
}
```
-The `set()` method replaces the signal's value entirely with a new value.
+El método `set()` reemplaza el valor del signal completamente con un nuevo valor.
-
-The buttons are already in the template. Now connect them to your methods by adding:
-1. Click handlers with `(click)`
-2. Disabled states with `[disabled]` when already in that status
+
+Los botones ya están en la plantilla. Ahora conéctalos a tus métodos agregando:
+1. Manejadores de clic con `(click)`
+2. Estados deshabilitados con `[disabled]` cuando ya están en ese estado
```html
-
+
@@ -93,8 +93,8 @@ The buttons are already in the template. Now connect them to your methods by add
-
-Add a `toggleStatus()` method that switches between online and offline using the `update()` method.
+
+Agrega un método `toggleStatus()` que cambie entre online y offline usando el método `update()`.
```ts
toggleStatus() {
@@ -102,12 +102,12 @@ toggleStatus() {
}
```
-The `update()` method takes a function that receives the current value and returns the new value. This is useful when you need to modify the existing value based on its current state.
+El método `update()` toma una función que recibe el valor actual y devuelve el nuevo valor. Esto es útil cuando necesitas modificar el valor existente basado en su estado actual.
-
-The toggle button is already in the template. Connect it to your `toggleStatus()` method:
+
+El botón toggle ya está en la plantilla. Conéctalo a tu método `toggleStatus()`:
```html
-Congratulations! You've created your first signal and learned how to update it using both `set()` and `update()` methods. The `signal()` function creates a reactive value that Angular tracks, and when you update it, your UI automatically reflects the changes.
+¡Felicidades! Has creado tu primer signal y aprendido cómo actualizarlo usando los métodos `set()` y `update()`. La función `signal()` crea un valor reactivo que Angular rastrea, y cuando lo actualizas, tu UI refleja automáticamente los cambios.
-Next, you'll learn [how to derive state from signals using computed](/tutorials/signals/2-deriving-state-with-computed-signals)!
+A continuación, aprenderás [cómo derivar estado de signals usando computed](/tutorials/signals/2-deriving-state-with-computed-signals)!
-
+
-You might notice `ChangeDetectionStrategy.OnPush` in the component decorator throughout this tutorial. This is a performance optimization for Angular components that use signals. For now, you can safely ignore it—just know it helps your app run faster when using signals! You can learn more in the [change detection strategies API docs](/api/core/ChangeDetectionStrategy).
+Puedes notar `ChangeDetectionStrategy.OnPush` en el decorador del componente a lo largo de este tutorial. Esta es una optimización de rendimiento para componentes Angular que usan signals. Por ahora, puedes ignorarlo de forma segura — solo debes saber que ayuda a tu aplicación a funcionar más rápido cuando usas signals. Puedes aprender más en la [documentación de la API de estrategias de detección de cambios](/api/core/ChangeDetectionStrategy).
diff --git a/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.en.md b/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.en.md
new file mode 100644
index 0000000..562424b
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.en.md
@@ -0,0 +1,111 @@
+# Reacting to signal changes with effect
+
+Now that you've learned [querying child elements with signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries), let's explore how to react to signal changes with effects. Effects are functions that run automatically when their dependencies change, making them perfect for side effects like logging, DOM manipulation, or API calls.
+
+**Important: Effects should be the last API you reach for.** Always prefer `computed()` for derived values and `linkedSignal()` for values that can be both derived and manually set. If you find yourself copying data from one signal to another with an effect, it's a sign you should move your source-of-truth higher up and use `computed()` or `linkedSignal()` instead. Effects are best for syncing signal state to imperative, non-signal APIs.
+
+In this activity, you'll learn how to use the `effect()` function appropriately for legitimate side effects that respond to signal changes.
+
+
+
+You have a theme manager app with signals already set up. Now you'll add effects to automatically react to signal changes.
+
+
+
+
+Add `effect` to your existing imports.
+
+```ts
+// Add effect to existing imports
+import {Component, signal, computed, effect, ChangeDetectionStrategy} from '@angular/core';
+```
+
+The `effect` function creates a reactive side effect that runs automatically when any signals it reads change.
+
+
+
+Add an effect that automatically saves the theme to local storage when it changes.
+
+```ts
+constructor() {
+ // Save theme to localStorage whenever it changes
+ effect(() => {
+ localStorage.setItem('theme', this.theme());
+ console.log('Theme saved to localStorage:', this.theme());
+ });
+}
+```
+
+This effect runs whenever the theme signal changes, automatically persisting the user's preference.
+
+
+
+Add an effect that logs when the user logs in or out.
+
+```ts
+constructor() {
+ // ... previous effect
+
+ // Log user activity changes
+ effect(() => {
+ const status = this.isLoggedIn() ? 'logged in' : 'logged out';
+ const user = this.username();
+ console.log(`User ${user} is ${status}`);
+ });
+}
+```
+
+This effect demonstrates how effects can read multiple signals and react to changes in any of them.
+
+
+
+Add an effect that sets up a timer and cleans up when the component is destroyed.
+
+```ts
+constructor() {
+ // ... previous effects
+
+ // Timer effect with cleanup
+ effect((onCleanup) => {
+ const interval = setInterval(() => {
+ console.log('Timer tick - Current theme:', this.theme());
+ }, 5000);
+
+ // Clean up the interval when the effect is destroyed
+ onCleanup(() => {
+ clearInterval(interval);
+ console.log('Timer cleaned up');
+ });
+ });
+}
+```
+
+This effect demonstrates how to clean up resources when effects are destroyed or re-run.
+
+
+
+Open the browser console and interact with the app:
+
+- **Toggle Theme** - See localStorage saves and timer logs
+- **Login/Logout** - See user activity logging
+- **Watch Timer** - See periodic theme logging every 5 seconds
+
+The effects run automatically whenever their tracked signals change!
+
+
+
+
+Excellent! You've now learned how to use effects with signals. Key concepts to remember:
+
+- **Effects are reactive**: They automatically run when any signal they read changes
+- **Side effects only**: Perfect for logging, DOM manipulation, API calls, and syncing to imperative APIs
+- **Cleanup**: Use the `onCleanup` callback to clean up resources like timers or subscriptions
+- **Automatic tracking**: Effects automatically track which signals they read and re-run when those signals change
+
+**Remember: Use effects sparingly!** The examples in this lesson (localStorage sync, logging, timers) are appropriate uses. Avoid effects for:
+
+- Deriving values from other signals - use `computed()` instead
+- Creating writable derived state - use `linkedSignal()` instead
+- Copying data between signals - restructure to use a shared source of truth
+
+Effects are powerful but should be your last resort when `computed()` and `linkedSignal()` can't solve your use case.
diff --git a/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.md b/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.md
index 562424b..fd23ffa 100644
--- a/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/10-reacting-to-signal-changes-with-effect/README.md
@@ -1,34 +1,34 @@
-# Reacting to signal changes with effect
+# Reaccionando a cambios de signal con effect
-Now that you've learned [querying child elements with signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries), let's explore how to react to signal changes with effects. Effects are functions that run automatically when their dependencies change, making them perfect for side effects like logging, DOM manipulation, or API calls.
+Ahora que has aprendido [cómo consultar elementos hijos con signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries), exploremos cómo reaccionar a cambios de signal con efectos. Los efectos son funciones que se ejecutan automáticamente cuando sus dependencias cambian, lo que los hace perfectos para efectos secundarios como logging, manipulación del DOM o llamadas a API.
-**Important: Effects should be the last API you reach for.** Always prefer `computed()` for derived values and `linkedSignal()` for values that can be both derived and manually set. If you find yourself copying data from one signal to another with an effect, it's a sign you should move your source-of-truth higher up and use `computed()` or `linkedSignal()` instead. Effects are best for syncing signal state to imperative, non-signal APIs.
+**Importante: Los efectos deberían ser la última API a la que recurras.** Siempre prefiere `computed()` para valores derivados y `linkedSignal()` para valores que pueden ser tanto derivados como establecidos manualmente. Si te encuentras copiando datos de un signal a otro con un efecto, es una señal de que deberías mover tu fuente de verdad más arriba y usar `computed()` o `linkedSignal()` en su lugar. Los efectos son mejores para sincronizar estado de signal con APIs imperativas que no son signals.
-In this activity, you'll learn how to use the `effect()` function appropriately for legitimate side effects that respond to signal changes.
+En esta actividad, aprenderás cómo usar la función `effect()` apropiadamente para efectos secundarios legítimos que responden a cambios de signal.
-You have a theme manager app with signals already set up. Now you'll add effects to automatically react to signal changes.
+Tienes una aplicación de gestor de temas con signals ya configurados. Ahora agregarás efectos para reaccionar automáticamente a cambios de signal.
-
-Add `effect` to your existing imports.
+
+Agrega `effect` a tus importaciones existentes.
```ts
-// Add effect to existing imports
+// Agregar effect a las importaciones existentes
import {Component, signal, computed, effect, ChangeDetectionStrategy} from '@angular/core';
```
-The `effect` function creates a reactive side effect that runs automatically when any signals it reads change.
+La función `effect` crea un efecto secundario reactivo que se ejecuta automáticamente cuando cualquier signal que lee cambia.
-
-Add an effect that automatically saves the theme to local storage when it changes.
+
+Agrega un efecto que guarde automáticamente el tema en localStorage cuando cambie.
```ts
constructor() {
- // Save theme to localStorage whenever it changes
+ // Guardar tema en localStorage cada vez que cambie
effect(() => {
localStorage.setItem('theme', this.theme());
console.log('Theme saved to localStorage:', this.theme());
@@ -36,17 +36,17 @@ constructor() {
}
```
-This effect runs whenever the theme signal changes, automatically persisting the user's preference.
+Este efecto se ejecuta cada vez que el signal del tema cambia, persistiendo automáticamente la preferencia del usuario.
-
-Add an effect that logs when the user logs in or out.
+
+Agrega un efecto que registre cuando el usuario inicia o cierra sesión.
```ts
constructor() {
- // ... previous effect
+ // ... efecto anterior
- // Log user activity changes
+ // Registrar cambios de actividad del usuario
effect(() => {
const status = this.isLoggedIn() ? 'logged in' : 'logged out';
const user = this.username();
@@ -55,23 +55,23 @@ constructor() {
}
```
-This effect demonstrates how effects can read multiple signals and react to changes in any of them.
+Este efecto demuestra cómo los efectos pueden leer múltiples signals y reaccionar a cambios en cualquiera de ellos.
-
-Add an effect that sets up a timer and cleans up when the component is destroyed.
+
+Agrega un efecto que configure un temporizador y se limpie cuando el componente sea destruido.
```ts
constructor() {
- // ... previous effects
+ // ... efectos anteriores
- // Timer effect with cleanup
+ // Efecto de temporizador con limpieza
effect((onCleanup) => {
const interval = setInterval(() => {
console.log('Timer tick - Current theme:', this.theme());
}, 5000);
- // Clean up the interval when the effect is destroyed
+ // Limpiar el intervalo cuando el efecto sea destruido
onCleanup(() => {
clearInterval(interval);
console.log('Timer cleaned up');
@@ -80,32 +80,32 @@ constructor() {
}
```
-This effect demonstrates how to clean up resources when effects are destroyed or re-run.
+Este efecto demuestra cómo limpiar recursos cuando los efectos son destruidos o re-ejecutados.
-
-Open the browser console and interact with the app:
+
+Abre la consola del navegador e interactúa con la aplicación:
-- **Toggle Theme** - See localStorage saves and timer logs
-- **Login/Logout** - See user activity logging
-- **Watch Timer** - See periodic theme logging every 5 seconds
+- **Toggle Theme** - Observa los guardados en localStorage y los logs del temporizador
+- **Login/Logout** - Observa el registro de actividad del usuario
+- **Watch Timer** - Observa el registro periódico del tema cada 5 segundos
-The effects run automatically whenever their tracked signals change!
+¡Los efectos se ejecutan automáticamente cada vez que sus signals rastreados cambian!
-Excellent! You've now learned how to use effects with signals. Key concepts to remember:
+¡Excelente! Ahora has aprendido cómo usar efectos con signals. Conceptos clave para recordar:
-- **Effects are reactive**: They automatically run when any signal they read changes
-- **Side effects only**: Perfect for logging, DOM manipulation, API calls, and syncing to imperative APIs
-- **Cleanup**: Use the `onCleanup` callback to clean up resources like timers or subscriptions
-- **Automatic tracking**: Effects automatically track which signals they read and re-run when those signals change
+- **Los efectos son reactivos**: Se ejecutan automáticamente cuando cualquier signal que leen cambia
+- **Solo efectos secundarios**: Perfectos para logging, manipulación del DOM, llamadas a API y sincronización con APIs imperativas
+- **Limpieza**: Usa el callback `onCleanup` para limpiar recursos como temporizadores o suscripciones
+- **Seguimiento automático**: Los efectos rastrean automáticamente qué signals leen y se re-ejecutan cuando esos signals cambian
-**Remember: Use effects sparingly!** The examples in this lesson (localStorage sync, logging, timers) are appropriate uses. Avoid effects for:
+**Recuerda: ¡Usa los efectos con moderación!** Los ejemplos en esta lección (sincronización con localStorage, logging, temporizadores) son usos apropiados. Evita los efectos para:
-- Deriving values from other signals - use `computed()` instead
-- Creating writable derived state - use `linkedSignal()` instead
-- Copying data between signals - restructure to use a shared source of truth
+- Derivar valores de otros signals - usa `computed()` en su lugar
+- Crear estado derivado editable - usa `linkedSignal()` en su lugar
+- Copiar datos entre signals - reestructura para usar una fuente de verdad compartida
-Effects are powerful but should be your last resort when `computed()` and `linkedSignal()` can't solve your use case.
+Los efectos son poderosos pero deberían ser tu último recurso cuando `computed()` y `linkedSignal()` no pueden resolver tu caso de uso.
diff --git a/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.en.md b/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.en.md
new file mode 100644
index 0000000..55de1ae
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.en.md
@@ -0,0 +1,12 @@
+# Want to dive deeper into signals?
+
+You can also learn more about signals with the following resources:
+
+
+
+ The official guide for Angular Signals.
+
+
+ Read about Angular's open source roadmap including current, future and accomplished projects.
+
+
diff --git a/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.md b/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.md
index 55de1ae..0086617 100644
--- a/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/11-next-steps/README.md
@@ -1,12 +1,12 @@
-# Want to dive deeper into signals?
+# ¿Quieres profundizar más en signals?
-You can also learn more about signals with the following resources:
+También puedes aprender más sobre signals con los siguientes recursos:
-
- The official guide for Angular Signals.
+
+ La guía oficial de Signals de Angular.
-
- Read about Angular's open source roadmap including current, future and accomplished projects.
+
+ Lee sobre el roadmap open source de Angular incluyendo proyectos actuales, futuros y completados.
diff --git a/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.en.md b/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.en.md
new file mode 100644
index 0000000..8305008
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.en.md
@@ -0,0 +1,109 @@
+# Deriving state with computed signals
+
+Now that you've learned [how to create and update signals](/tutorials/signals/1-creating-and-updating-your-first-signal), let's learn about computed signals. Computed signals are derived values that automatically update when their dependencies change. They're perfect for creating reactive calculations based on other signals.
+
+In this activity, you'll learn how to use the `computed()` function to create derived state that updates automatically when the underlying signals change.
+
+Let's enhance our user status system by adding computed values that derive information from our user status signal. The starter code now includes three status options: `'online'`, `'away'`, and `'offline'`.
+
+
+
+
+
+
+Add `computed` to your existing imports.
+
+```ts
+// Add computed to existing imports
+import {Component, signal, computed, ChangeDetectionStrategy} from '@angular/core';
+```
+
+
+
+
+Add a computed signal that determines if notifications should be enabled based on user status.
+
+```ts
+notificationsEnabled = computed(() => this.userStatus() === 'online');
+```
+
+This computed signal will automatically recalculate whenever the `userStatus` signal changes. Notice how we call `this.userStatus()` inside the computed function to read the signal's value.
+
+
+
+Add a computed signal that creates a descriptive message based on the user status.
+
+```ts
+statusMessage = computed(() => {
+ const status = this.userStatus();
+ switch (status) {
+ case 'online': return 'Available for meetings and messages';
+ case 'away': return 'Temporarily away, will respond soon';
+ case 'offline': return 'Not available, check back later';
+ default: return 'Status unknown';
+ }
+});
+```
+
+This shows how computed signals can handle more complex logic with switch statements and string transformations.
+
+
+
+Add a computed signal that calculates if the user is within their working hours.
+
+```ts
+isWithinWorkingHours = computed(() => {
+ const now = new Date();
+ const hour = now.getHours();
+ const isWeekday = now.getDay() > 0 && now.getDay() < 6;
+ return isWeekday && hour >= 9 && hour < 17 && this.userStatus() !== 'offline';
+});
+```
+
+This demonstrates how computed signals can perform calculations and combine multiple data sources. The value updates automatically when the `userStatus` changes.
+
+
+
+The template already has placeholders showing "Loading...". Replace them with your computed signals:
+
+1. For notifications, replace `Loading...` with an @if block:
+
+```angular-html
+@if (notificationsEnabled()) {
+ Enabled
+} @else {
+ Disabled
+}
+```
+
+2. For the message, replace `Loading...` with:
+
+```angular-html
+{{ statusMessage() }}
+```
+
+3. For working hours, replace `Loading...` with an @if block:
+
+```angular-html
+@if (isWithinWorkingHours()) {
+ Yes
+} @else {
+ No
+}
+```
+
+Notice how computed signals are called just like regular signals - with parentheses!
+
+
+
+
+Excellent! You've now learned how to create computed signals.
+
+Here are some key points to remember:
+
+- **Computed signals are reactive**: They automatically update when their dependencies change
+- **They're read-only**: You can't directly set computed values, they're derived from other signals
+- **They can contain complex logic**: Use them for calculations, transformations, and derived state
+- **They provide a way to make performant computations based on dynamic state**: Angular only recalculates them when their dependencies actually change
+
+In the next lesson, you'll learn about [a different way to derive state with linkedSignals](/tutorials/signals/3-deriving-state-with-linked-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.md b/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.md
index 8305008..5b2fcf2 100644
--- a/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/2-deriving-state-with-computed-signals/README.md
@@ -1,37 +1,37 @@
-# Deriving state with computed signals
+# Derivando estado con computed signals
-Now that you've learned [how to create and update signals](/tutorials/signals/1-creating-and-updating-your-first-signal), let's learn about computed signals. Computed signals are derived values that automatically update when their dependencies change. They're perfect for creating reactive calculations based on other signals.
+Ahora que has aprendido [cómo crear y actualizar signals](/tutorials/signals/1-creating-and-updating-your-first-signal), aprendamos sobre los computed signals. Los computed signals son valores derivados que se actualizan automáticamente cuando sus dependencias cambian. Son perfectos para crear cálculos reactivos basados en otros signals.
-In this activity, you'll learn how to use the `computed()` function to create derived state that updates automatically when the underlying signals change.
+En esta actividad, aprenderás cómo usar la función `computed()` para crear estado derivado que se actualiza automáticamente cuando los signals subyacentes cambian.
-Let's enhance our user status system by adding computed values that derive information from our user status signal. The starter code now includes three status options: `'online'`, `'away'`, and `'offline'`.
+Mejoremos nuestro sistema de estado de usuario agregando valores computed que deriven información de nuestro signal de estado de usuario. El código inicial ahora incluye tres opciones de estado: `'online'`, `'away'` y `'offline'`.
-
-Add `computed` to your existing imports.
+
+Agrega `computed` a tus importaciones existentes.
```ts
-// Add computed to existing imports
+// Agregar computed a las importaciones existentes
import {Component, signal, computed, ChangeDetectionStrategy} from '@angular/core';
```
-
-Add a computed signal that determines if notifications should be enabled based on user status.
+
+Agrega un computed signal que determine si las notificaciones deberían estar habilitadas según el estado del usuario.
```ts
notificationsEnabled = computed(() => this.userStatus() === 'online');
```
-This computed signal will automatically recalculate whenever the `userStatus` signal changes. Notice how we call `this.userStatus()` inside the computed function to read the signal's value.
+Este computed signal se recalculará automáticamente cada vez que el signal `userStatus` cambie. Observa cómo llamamos `this.userStatus()` dentro de la función computed para leer el valor del signal.
-
-Add a computed signal that creates a descriptive message based on the user status.
+
+Agrega un computed signal que cree un mensaje descriptivo basado en el estado del usuario.
```ts
statusMessage = computed(() => {
@@ -45,11 +45,11 @@ statusMessage = computed(() => {
});
```
-This shows how computed signals can handle more complex logic with switch statements and string transformations.
+Esto muestra cómo los computed signals pueden manejar lógica más compleja con sentencias switch y transformaciones de strings.
-
-Add a computed signal that calculates if the user is within their working hours.
+
+Agrega un computed signal que calcule si el usuario está dentro de su horario laboral.
```ts
isWithinWorkingHours = computed(() => {
@@ -60,13 +60,13 @@ isWithinWorkingHours = computed(() => {
});
```
-This demonstrates how computed signals can perform calculations and combine multiple data sources. The value updates automatically when the `userStatus` changes.
+Esto demuestra cómo los computed signals pueden realizar cálculos y combinar múltiples fuentes de datos. El valor se actualiza automáticamente cuando `userStatus` cambia.
-
-The template already has placeholders showing "Loading...". Replace them with your computed signals:
+
+La plantilla ya tiene placeholders mostrando "Loading...". Reemplázalos con tus computed signals:
-1. For notifications, replace `Loading...` with an @if block:
+1. Para notificaciones, reemplaza `Loading...` con un bloque @if:
```angular-html
@if (notificationsEnabled()) {
@@ -76,13 +76,13 @@ The template already has placeholders showing "Loading...". Replace them with yo
}
```
-2. For the message, replace `Loading...` with:
+2. Para el mensaje, reemplaza `Loading...` con:
```angular-html
{{ statusMessage() }}
```
-3. For working hours, replace `Loading...` with an @if block:
+3. Para horario laboral, reemplaza `Loading...` con un bloque @if:
```angular-html
@if (isWithinWorkingHours()) {
@@ -92,18 +92,18 @@ The template already has placeholders showing "Loading...". Replace them with yo
}
```
-Notice how computed signals are called just like regular signals - with parentheses!
+Observa cómo los computed signals se llaman igual que los signals regulares — ¡con paréntesis!
-Excellent! You've now learned how to create computed signals.
+¡Excelente! Ahora has aprendido cómo crear computed signals.
-Here are some key points to remember:
+Aquí hay algunos puntos clave para recordar:
-- **Computed signals are reactive**: They automatically update when their dependencies change
-- **They're read-only**: You can't directly set computed values, they're derived from other signals
-- **They can contain complex logic**: Use them for calculations, transformations, and derived state
-- **They provide a way to make performant computations based on dynamic state**: Angular only recalculates them when their dependencies actually change
+- **Los computed signals son reactivos**: Se actualizan automáticamente cuando sus dependencias cambian
+- **Son de solo lectura**: No puedes establecer valores computed directamente, se derivan de otros signals
+- **Pueden contener lógica compleja**: Úsalos para cálculos, transformaciones y estado derivado
+- **Proporcionan una forma de hacer cómputos eficientes basados en estado dinámico**: Angular solo los recalcula cuando sus dependencias realmente cambian
-In the next lesson, you'll learn about [a different way to derive state with linkedSignals](/tutorials/signals/3-deriving-state-with-linked-signals)!
+En la próxima lección, aprenderás sobre [una forma diferente de derivar estado con linkedSignals](/tutorials/signals/3-deriving-state-with-linked-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.en.md b/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.en.md
new file mode 100644
index 0000000..f1980a4
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.en.md
@@ -0,0 +1,95 @@
+# Deriving state with linked signals
+
+Now that you've learned [how to derive state with computed signals](/tutorials/signals/2-deriving-state-with-computed-signals), you created a computed signal for `notificationsEnabled` that automatically followed your user status. But what if users want to manually disable notifications even when they're online? That's where linked signals come in.
+
+Linked signals are writable signals that maintain a reactive connection to their source signals. They're perfect for creating state that normally follows a computation but can be overridden when needed.
+
+In this activity, you'll learn how `linkedSignal()` differs from `computed()` by enhancing the previous user status system's computed `notificationsEnabled` to a writable linked signal.
+
+
+
+
+
+
+Add `linkedSignal` to your existing imports.
+
+```ts
+// Add linkedSignal to existing imports
+import {Component, signal, computed, linkedSignal, ChangeDetectionStrategy} from '@angular/core';
+```
+
+
+
+
+Replace the computed `notificationsEnabled` with a linkedSignal using the exact same expression:
+
+```ts
+// Previously (from lesson 2):
+// notificationsEnabled = computed(() => this.userStatus() === 'online');
+
+// Now with linkedSignal - same expression, but writable:
+notificationsEnabled = linkedSignal(() => this.userStatus() === 'online');
+```
+
+The expression is identical, but linkedSignal creates a writable signal. It will still automatically update when `userStatus` changes, but you can also set it manually.
+
+
+
+Add a method to demonstrate that linked signals can be written to directly:
+
+```ts
+toggleNotifications() {
+ // This works with linkedSignal but would error with computed!
+ this.notificationsEnabled.set(!this.notificationsEnabled());
+}
+```
+
+This is the key difference: computed signals are read-only, but linked signals can be updated manually while still maintaining their reactive connection.
+
+
+
+Update your template to add a toggle button for notifications:
+
+```angular-html
+
+```
+
+
+
+
+Now test the behavior:
+
+1. Change the user status - notice how `notificationsEnabled` updates automatically
+2. Manually toggle notifications - it overrides the computed value
+3. Change status again - the linked signal re-syncs with its computation
+
+This demonstrates that linked signals maintain their reactive connection even after being manually set!
+
+
+
+
+Excellent! You've learned the key differences between computed and linked signals:
+
+- **Computed signals**: Read-only, always derived from other signals
+- **Linked signals**: Writable, can be both derived AND manually updated
+- **Use computed when**: The value should always be calculated
+- **Use linkedSignal when**: You need a default computation that can be overridden
+
+In the next lesson, you'll learn [how to manage async data with signals](/tutorials/signals/4-managing-async-data-with-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md b/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md
index f1980a4..3fdd061 100644
--- a/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/3-deriving-state-with-linked-signals/README.md
@@ -1,54 +1,54 @@
-# Deriving state with linked signals
+# Derivando estado con linked signals
-Now that you've learned [how to derive state with computed signals](/tutorials/signals/2-deriving-state-with-computed-signals), you created a computed signal for `notificationsEnabled` that automatically followed your user status. But what if users want to manually disable notifications even when they're online? That's where linked signals come in.
+Ahora que has aprendido [cómo derivar estado con computed signals](/tutorials/signals/2-deriving-state-with-computed-signals), creaste un computed signal para `notificationsEnabled` que seguía automáticamente tu estado de usuario. Pero ¿qué pasa si los usuarios quieren deshabilitar manualmente las notificaciones incluso cuando están en línea? Ahí es donde entran los linked signals.
-Linked signals are writable signals that maintain a reactive connection to their source signals. They're perfect for creating state that normally follows a computation but can be overridden when needed.
+Los linked signals son signals editables que mantienen una conexión reactiva con sus signals fuente. Son perfectos para crear estado que normalmente sigue un cómputo pero puede ser anulado cuando sea necesario.
-In this activity, you'll learn how `linkedSignal()` differs from `computed()` by enhancing the previous user status system's computed `notificationsEnabled` to a writable linked signal.
+En esta actividad, aprenderás cómo `linkedSignal()` se diferencia de `computed()` mejorando el computed `notificationsEnabled` del sistema de estado de usuario anterior a un linked signal editable.
-
-Add `linkedSignal` to your existing imports.
+
+Agrega `linkedSignal` a tus importaciones existentes.
```ts
-// Add linkedSignal to existing imports
+// Agregar linkedSignal a las importaciones existentes
import {Component, signal, computed, linkedSignal, ChangeDetectionStrategy} from '@angular/core';
```
-
-Replace the computed `notificationsEnabled` with a linkedSignal using the exact same expression:
+
+Reemplaza el computed `notificationsEnabled` con un linkedSignal usando exactamente la misma expresión:
```ts
-// Previously (from lesson 2):
+// Anteriormente (de la lección 2):
// notificationsEnabled = computed(() => this.userStatus() === 'online');
-// Now with linkedSignal - same expression, but writable:
+// Ahora con linkedSignal - misma expresión, pero editable:
notificationsEnabled = linkedSignal(() => this.userStatus() === 'online');
```
-The expression is identical, but linkedSignal creates a writable signal. It will still automatically update when `userStatus` changes, but you can also set it manually.
+La expresión es idéntica, pero linkedSignal crea un signal editable. Se seguirá actualizando automáticamente cuando `userStatus` cambie, pero también puedes establecerlo manualmente.
-
-Add a method to demonstrate that linked signals can be written to directly:
+
+Agrega un método para demostrar que los linked signals pueden escribirse directamente:
```ts
toggleNotifications() {
- // This works with linkedSignal but would error with computed!
+ // Esto funciona con linkedSignal pero daría error con computed!
this.notificationsEnabled.set(!this.notificationsEnabled());
}
```
-This is the key difference: computed signals are read-only, but linked signals can be updated manually while still maintaining their reactive connection.
+Esta es la diferencia clave: los computed signals son de solo lectura, pero los linked signals pueden actualizarse manualmente mientras mantienen su conexión reactiva.
-
-Update your template to add a toggle button for notifications:
+
+Actualiza tu plantilla para agregar un botón de alternancia para notificaciones:
```angular-html
@@ -67,29 +67,29 @@ Update your template to add a toggle button for notifications:
}
-
+
```
-
-Now test the behavior:
+
+Ahora prueba el comportamiento:
-1. Change the user status - notice how `notificationsEnabled` updates automatically
-2. Manually toggle notifications - it overrides the computed value
-3. Change status again - the linked signal re-syncs with its computation
+1. Cambia el estado del usuario - observa cómo `notificationsEnabled` se actualiza automáticamente
+2. Alterna manualmente las notificaciones - anula el valor computed
+3. Cambia el estado nuevamente - el linked signal se re-sincroniza con su cómputo
-This demonstrates that linked signals maintain their reactive connection even after being manually set!
+¡Esto demuestra que los linked signals mantienen su conexión reactiva incluso después de ser establecidos manualmente!
-Excellent! You've learned the key differences between computed and linked signals:
+¡Excelente! Has aprendido las diferencias clave entre computed y linked signals:
-- **Computed signals**: Read-only, always derived from other signals
-- **Linked signals**: Writable, can be both derived AND manually updated
-- **Use computed when**: The value should always be calculated
-- **Use linkedSignal when**: You need a default computation that can be overridden
+- **Computed signals**: Solo lectura, siempre derivados de otros signals
+- **Linked signals**: Editables, pueden ser tanto derivados como actualizados manualmente
+- **Usa computed cuando**: El valor siempre debe ser calculado
+- **Usa linkedSignal cuando**: Necesitas un cómputo predeterminado que pueda ser anulado
-In the next lesson, you'll learn [how to manage async data with signals](/tutorials/signals/4-managing-async-data-with-signals)!
+En la próxima lección, aprenderás [cómo gestionar datos asíncronos con signals](/tutorials/signals/4-managing-async-data-with-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md b/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md
new file mode 100644
index 0000000..da3a520
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.en.md
@@ -0,0 +1,110 @@
+# Managing async data with signals using the Resources API
+
+Now that you've learned [how to derive state with linked signals](/tutorials/signals/3-deriving-state-with-linked-signals), let's explore how to handle asynchronous data with the Resource API. The Resource API provides a powerful way to manage async operations using signals, with built-in loading states, error handling, and request management.
+
+In this activity, you'll learn how to use the `resource()` function to load data asynchronously and how to handle different states of async operations by building a user profile loader that demonstrates the Resource API in action.
+
+
+
+
+
+
+Add `resource` to your existing imports and import the fake API function.
+
+```ts
+// Add resource to existing imports
+import {Component, signal, computed, resource, ChangeDetectionStrategy} from '@angular/core';
+// Import mock API function
+import {loadUser} from './user-api';
+```
+
+
+
+
+Add a property in the component class that creates a resource to load user data based on a user ID signal.
+
+```ts
+userId = signal(1);
+
+userResource = resource({
+ params: () => ({ id: this.userId() }),
+ loader: (params) => loadUser(params.params.id)
+});
+```
+
+
+
+
+Add methods to change the user ID and reload the resource.
+
+```ts
+loadUser(id: number) {
+ this.userId.set(id);
+}
+
+reloadUser() {
+ this.userResource.reload();
+}
+```
+
+Changing the params signal automatically triggers a reload, or you can manually reload with `reload()`.
+
+
+
+Add computed signals to access different states of the resource.
+
+```ts
+isLoading = computed(() => this.userResource.status() === 'loading');
+hasError = computed(() => this.userResource.status() === 'error');
+```
+
+Resources provide a `status()` signal that can be 'loading', 'success', or 'error', a `value()` signal for the loaded data, and a `hasValue()` method that safely checks if data is available.
+
+
+
+The template structure is already provided. Now connect everything:
+
+Part 1. **Add click handlers to the buttons:**
+
+```html
+
+
+
+
+```
+
+Part 2. **Replace the placeholder with resource state handling:**
+
+```angular-html
+@if (isLoading()) {
+
Loading user...
+} @else if (hasError()) {
+
Error: {{ userResource.error()?.message }}
+} @else if (userResource.hasValue()) {
+
+
{{ userResource.value().name }}
+
{{ userResource.value().email }}
+
+}
+```
+
+The resource provides different methods to check its state:
+
+- `isLoading()` - true when fetching data
+- `hasError()` - true when an error occurred
+- `userResource.hasValue()` - true when data is available
+- `userResource.value()` - access the loaded data
+- `userResource.error()` - access error information
+
+
+
+
+
+Excellent! You've now learned how to use the Resource API with signals. Key concepts to remember:
+
+- **Resources are reactive**: They automatically reload when params change
+- **Built-in state management**: Resources provide `status()`, `value()`, and `error()` signals
+- **Automatic cleanup**: Resources handle request cancellation and cleanup automatically
+- **Manual control**: You can manually reload or abort requests when needed
+
+In the next lesson, you'll learn [how to pass data to components with input signals](/tutorials/signals/5-component-communication-with-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md b/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md
index da3a520..7743786 100644
--- a/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md
@@ -1,27 +1,27 @@
-# Managing async data with signals using the Resources API
+# Gestionando datos asíncronos con signals usando la API de Resources
-Now that you've learned [how to derive state with linked signals](/tutorials/signals/3-deriving-state-with-linked-signals), let's explore how to handle asynchronous data with the Resource API. The Resource API provides a powerful way to manage async operations using signals, with built-in loading states, error handling, and request management.
+Ahora que has aprendido [cómo derivar estado con linked signals](/tutorials/signals/3-deriving-state-with-linked-signals), exploremos cómo manejar datos asíncronos con la API de Resource. La API de Resource proporciona una forma potente de gestionar operaciones asíncronas usando signals, con estados de carga integrados, manejo de errores y gestión de solicitudes.
-In this activity, you'll learn how to use the `resource()` function to load data asynchronously and how to handle different states of async operations by building a user profile loader that demonstrates the Resource API in action.
+En esta actividad, aprenderás cómo usar la función `resource()` para cargar datos de forma asíncrona y cómo manejar diferentes estados de operaciones asíncronas construyendo un cargador de perfil de usuario que demuestra la API de Resource en acción.
-
-Add `resource` to your existing imports and import the fake API function.
+
+Agrega `resource` a tus importaciones existentes e importa la función de API falsa.
```ts
-// Add resource to existing imports
+// Agregar resource a las importaciones existentes
import {Component, signal, computed, resource, ChangeDetectionStrategy} from '@angular/core';
-// Import mock API function
+// Importar función de API mock
import {loadUser} from './user-api';
```
-
-Add a property in the component class that creates a resource to load user data based on a user ID signal.
+
+Agrega una propiedad en la clase del componente que cree un resource para cargar datos de usuario basados en un signal de ID de usuario.
```ts
userId = signal(1);
@@ -34,8 +34,8 @@ userResource = resource({
-
-Add methods to change the user ID and reload the resource.
+
+Agrega métodos para cambiar el ID de usuario y recargar el resource.
```ts
loadUser(id: number) {
@@ -47,24 +47,24 @@ reloadUser() {
}
```
-Changing the params signal automatically triggers a reload, or you can manually reload with `reload()`.
+Cambiar el signal de params automáticamente dispara una recarga, o puedes recargar manualmente con `reload()`.
-
-Add computed signals to access different states of the resource.
+
+Agrega computed signals para acceder a diferentes estados del resource.
```ts
isLoading = computed(() => this.userResource.status() === 'loading');
hasError = computed(() => this.userResource.status() === 'error');
```
-Resources provide a `status()` signal that can be 'loading', 'success', or 'error', a `value()` signal for the loaded data, and a `hasValue()` method that safely checks if data is available.
+Los resources proporcionan un signal `status()` que puede ser 'loading', 'success' o 'error', un signal `value()` para los datos cargados y un método `hasValue()` que verifica de forma segura si los datos están disponibles.
-
-The template structure is already provided. Now connect everything:
+
+La estructura de la plantilla ya está proporcionada. Ahora conecta todo:
-Part 1. **Add click handlers to the buttons:**
+Parte 1. **Agrega manejadores de clic a los botones:**
```html
@@ -73,7 +73,7 @@ Part 1. **Add click handlers to the buttons:**
```
-Part 2. **Replace the placeholder with resource state handling:**
+Parte 2. **Reemplaza el placeholder con el manejo de estado del resource:**
```angular-html
@if (isLoading()) {
@@ -88,23 +88,23 @@ Part 2. **Replace the placeholder with resource state handling:**
}
```
-The resource provides different methods to check its state:
+El resource proporciona diferentes métodos para verificar su estado:
-- `isLoading()` - true when fetching data
-- `hasError()` - true when an error occurred
-- `userResource.hasValue()` - true when data is available
-- `userResource.value()` - access the loaded data
-- `userResource.error()` - access error information
+- `isLoading()` - verdadero cuando está obteniendo datos
+- `hasError()` - verdadero cuando ocurrió un error
+- `userResource.hasValue()` - verdadero cuando los datos están disponibles
+- `userResource.value()` - accede a los datos cargados
+- `userResource.error()` - accede a la información del error
-Excellent! You've now learned how to use the Resource API with signals. Key concepts to remember:
+¡Excelente! Ahora has aprendido cómo usar la API de Resource con signals. Conceptos clave para recordar:
-- **Resources are reactive**: They automatically reload when params change
-- **Built-in state management**: Resources provide `status()`, `value()`, and `error()` signals
-- **Automatic cleanup**: Resources handle request cancellation and cleanup automatically
-- **Manual control**: You can manually reload or abort requests when needed
+- **Los resources son reactivos**: Se recargan automáticamente cuando los params cambian
+- **Gestión de estado integrada**: Los resources proporcionan signals `status()`, `value()` y `error()`
+- **Limpieza automática**: Los resources manejan la cancelación y limpieza de solicitudes automáticamente
+- **Control manual**: Puedes recargar o abortar solicitudes manualmente cuando sea necesario
-In the next lesson, you'll learn [how to pass data to components with input signals](/tutorials/signals/5-component-communication-with-signals)!
+En la próxima lección, aprenderás [cómo pasar datos a componentes con input signals](/tutorials/signals/5-component-communication-with-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md b/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md
new file mode 100644
index 0000000..636cac4
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.en.md
@@ -0,0 +1,105 @@
+# Passing data to components with input signals
+
+Now that you've learned [managing async data with signals](/tutorials/signals/4-managing-async-data-with-signals), let's explore Angular's signal-based `input()` API for passing data from parent to child components, making component data flow more reactive and efficient. If you're familiar with component props from other frameworks, inputs are the same idea.
+
+In this activity, you'll add signal inputs to a product card component and see how parent data flows down reactively.
+
+
+
+
+
+
+Add signal `input()` functions to receive data in the `product-card` component.
+
+```ts
+// Add imports for signal inputs
+import {Component, input, ChangeDetectionStrategy} from '@angular/core';
+
+// Add these signal inputs
+name = input.required();
+price = input.required();
+available = input(true);
+```
+
+Notice how `input.required()` creates an input that must be provided, while `input()` with a default value is optional.
+
+
+
+Update the template in `product-card` to display the signal input values.
+
+```angular-html
+
+
{{ name() }}
+
\${{ price() }}
+
Status:
+ @if (available()) {
+ Available
+ } @else {
+ Out of Stock
+ }
+
+
+```
+
+Input signals work just like regular signals in templates - call them as functions to access their values.
+
+
+
+Update the `product-card` usage in `app.ts` to pass dynamic signal values instead of static ones.
+
+```html
+
+
+
+
+
+```
+
+The square brackets `[]` create property bindings that pass the current signal values to the child.
+
+
+
+Add methods in `app.ts` to update the parent signals and see how the child component reacts automatically.
+
+```ts
+updateProduct() {
+ this.productName.set('Updated Product');
+ this.productPrice.set(149);
+}
+
+toggleAvailability() {
+ this.productAvailable.set(!this.productAvailable());
+}
+```
+
+```html
+
+
+
+
+
+```
+
+When parent signals change, the child component automatically receives and displays the new values!
+
+
+
+
+Excellent! You've learned how signal inputs work:
+
+- **Signal inputs** - Use `input()` and `input.required()` to receive data from parent components
+- **Reactive updates** - Child components automatically update when parent signal values change
+- **Type safety** - Signal inputs provide full TypeScript type checking
+- **Default values** - Optional inputs can have default values while required inputs must be provided
+
+Signal inputs make component communication more reactive and eliminate the need for `OnChanges` lifecycle hooks in many cases.
+
+In the next lesson, you'll learn about [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md b/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md
index 636cac4..0fc2956 100644
--- a/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/5-component-communication-with-signals/README.md
@@ -1,31 +1,31 @@
-# Passing data to components with input signals
+# Pasando datos a componentes con input signals
-Now that you've learned [managing async data with signals](/tutorials/signals/4-managing-async-data-with-signals), let's explore Angular's signal-based `input()` API for passing data from parent to child components, making component data flow more reactive and efficient. If you're familiar with component props from other frameworks, inputs are the same idea.
+Ahora que has aprendido [cómo gestionar datos asíncronos con signals](/tutorials/signals/4-managing-async-data-with-signals), exploremos la API `input()` basada en signals de Angular para pasar datos de componentes padre a hijo, haciendo que el flujo de datos del componente sea más reactivo y eficiente. Si estás familiarizado con las props de componentes de otros frameworks, los inputs son la misma idea.
-In this activity, you'll add signal inputs to a product card component and see how parent data flows down reactively.
+En esta actividad, agregarás signal inputs a un componente de tarjeta de producto y verás cómo los datos del padre fluyen hacia abajo de forma reactiva.
-
-Add signal `input()` functions to receive data in the `product-card` component.
+
+Agrega funciones `input()` de signal para recibir datos en el componente `product-card`.
```ts
-// Add imports for signal inputs
+// Agregar importaciones para signal inputs
import {Component, input, ChangeDetectionStrategy} from '@angular/core';
-// Add these signal inputs
+// Agregar estos signal inputs
name = input.required();
price = input.required();
available = input(true);
```
-Notice how `input.required()` creates an input that must be provided, while `input()` with a default value is optional.
+Observa cómo `input.required()` crea un input que debe ser proporcionado, mientras que `input()` con un valor predeterminado es opcional.
-
-Update the template in `product-card` to display the signal input values.
+
+Actualiza la plantilla en `product-card` para mostrar los valores de los signal inputs.
```angular-html
@@ -41,21 +41,21 @@ Update the template in `product-card` to display the signal input values.
```
-Input signals work just like regular signals in templates - call them as functions to access their values.
+Los input signals funcionan igual que los signals regulares en las plantillas — llámalos como funciones para acceder a sus valores.
-
-Update the `product-card` usage in `app.ts` to pass dynamic signal values instead of static ones.
+
+Actualiza el uso de `product-card` en `app.ts` para pasar valores dinámicos de signals en lugar de valores estáticos.
```html
-
+
-
+
```
-The square brackets `[]` create property bindings that pass the current signal values to the child.
+Los corchetes `[]` crean enlaces de propiedad que pasan los valores actuales de los signals al hijo.
-
-Add methods in `app.ts` to update the parent signals and see how the child component reacts automatically.
+
+Agrega métodos en `app.ts` para actualizar los signals del padre y ver cómo el componente hijo reacciona automáticamente.
```ts
updateProduct() {
@@ -81,25 +81,25 @@ toggleAvailability() {
```
```html
-
+
```
-When parent signals change, the child component automatically receives and displays the new values!
+¡Cuando los signals del padre cambian, el componente hijo recibe y muestra automáticamente los nuevos valores!
-Excellent! You've learned how signal inputs work:
+¡Excelente! Has aprendido cómo funcionan los signal inputs:
-- **Signal inputs** - Use `input()` and `input.required()` to receive data from parent components
-- **Reactive updates** - Child components automatically update when parent signal values change
-- **Type safety** - Signal inputs provide full TypeScript type checking
-- **Default values** - Optional inputs can have default values while required inputs must be provided
+- **Signal inputs** - Usa `input()` y `input.required()` para recibir datos de componentes padre
+- **Actualizaciones reactivas** - Los componentes hijo se actualizan automáticamente cuando los valores de los signals del padre cambian
+- **Seguridad de tipos** - Los signal inputs proporcionan verificación de tipos completa de TypeScript
+- **Valores predeterminados** - Los inputs opcionales pueden tener valores predeterminados mientras que los inputs requeridos deben ser proporcionados
-Signal inputs make component communication more reactive and eliminate the need for `OnChanges` lifecycle hooks in many cases.
+Los signal inputs hacen que la comunicación entre componentes sea más reactiva y eliminan la necesidad de los hooks de ciclo de vida `OnChanges` en muchos casos.
-In the next lesson, you'll learn about [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals)!
+En la próxima lección, aprenderás sobre [el enlace bidireccional con model signals](/tutorials/signals/6-two-way-binding-with-model-signals)!
diff --git a/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md b/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md
new file mode 100644
index 0000000..f451bc0
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.en.md
@@ -0,0 +1,134 @@
+# Two-way binding with model signals
+
+Now that you've learned [passing data to components with input signals](/tutorials/signals/5-component-communication-with-signals), let's explore Angular's `model()` API for two-way binding. Model signals are perfect for UI components like checkboxes, sliders, or custom form controls where the component needs to both receive a value AND update it.
+
+In this activity, you'll create a custom checkbox component that manages its own state while keeping the parent synchronized.
+
+
+
+
+
+
+Create a model signal in the `custom-checkbox` component that can both receive and update the parent's value.
+
+```ts
+// Add imports for model signals
+import {Component, model, input, ChangeDetectionStrategy} from '@angular/core';
+
+// Model signal for two-way binding
+checked = model.required();
+
+// Optional input for label
+label = input('');
+```
+
+Unlike `input()` signals which are read-only, `model()` signals can be both read and written to.
+
+
+
+Build the checkbox template that responds to clicks and updates its own model.
+
+```html
+
+```
+
+The component reads from its model signal and has a method to update it.
+
+
+
+Implement the toggle method that updates the model signal when the checkbox is clicked.
+
+```ts
+toggle() {
+ // This updates BOTH the component's state AND the parent's model!
+ this.checked.set(!this.checked());
+}
+```
+
+When the child component calls `this.checked.set()`, it automatically propagates the change back to the parent. This is the key difference from `input()` signals.
+
+
+
+First, uncomment the model signal properties and methods in `app.ts`:
+
+```ts
+// Parent signal models
+agreedToTerms = model(false);
+enableNotifications = model(true);
+
+// Methods to test two-way binding
+toggleTermsFromParent() {
+ this.agreedToTerms.set(!this.agreedToTerms());
+}
+
+resetAll() {
+ this.agreedToTerms.set(false);
+ this.enableNotifications.set(false);
+}
+```
+
+Then update the template:
+
+Part 1. **Uncomment the checkboxes and add two-way binding:**
+
+- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="agreedToTerms"` for the first checkbox
+- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="enableNotifications"` for the second
+
+Part 2. **Replace the `???` placeholders with @if blocks:**
+
+```angular-html
+@if (agreedToTerms()) {
+ Yes
+} @else {
+ No
+}
+
+@if (enableNotifications()) {
+ Yes
+} @else {
+ No
+}
+```
+
+Part 3. **Add click handlers to the buttons:**
+
+```html
+
+
+```
+
+The `[(checked)]` syntax creates two-way binding - data flows down to the component AND changes flow back up to the parent by emitting an event that references the signal itself and does _not_ call the signal getter directly.
+
+
+
+Interact with your app to see two-way binding in action:
+
+1. **Click checkboxes** - Component updates its own state and notifies parent
+2. **Click "Toggle Terms from Parent"** - Parent updates propagate down to component
+3. **Click "Reset All"** - Parent resets both models and components update automatically
+
+Both the parent and child can update the shared state, and both stay in sync automatically!
+
+
+
+
+Perfect! You've learned how model signals enable two-way binding:
+
+- **Model signals** - Use `model()` and `model.required()` for values that can be both read and written
+- **Two-way binding** - Use `[(property)]` syntax to bind parent signals to child models
+- **Perfect for UI components** - Checkboxes, form controls, and widgets that need to manage their own state
+- **Automatic synchronization** - Parent and child stay in sync without manual event handling
+
+**When to use `model()` vs `input()`:**
+
+- Use `input()` for data that only flows down (display data, configuration)
+- Use `model()` for UI components that need to update their own value (form controls, toggles)
+
+In the next lesson, you'll learn about [using signals with services](/tutorials/signals/7-using-signals-with-services)!
diff --git a/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md b/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md
index f451bc0..d402823 100644
--- a/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/6-two-way-binding-with-model-signals/README.md
@@ -1,32 +1,32 @@
-# Two-way binding with model signals
+# Enlace bidireccional con model signals
-Now that you've learned [passing data to components with input signals](/tutorials/signals/5-component-communication-with-signals), let's explore Angular's `model()` API for two-way binding. Model signals are perfect for UI components like checkboxes, sliders, or custom form controls where the component needs to both receive a value AND update it.
+Ahora que has aprendido [cómo pasar datos a componentes con input signals](/tutorials/signals/5-component-communication-with-signals), exploremos la API `model()` de Angular para el enlace bidireccional. Los model signals son perfectos para componentes de UI como checkboxes, sliders o controles de formulario personalizados donde el componente necesita tanto recibir un valor como actualizarlo.
-In this activity, you'll create a custom checkbox component that manages its own state while keeping the parent synchronized.
+En esta actividad, crearás un componente de checkbox personalizado que gestiona su propio estado mientras mantiene sincronizado al padre.
-
-Create a model signal in the `custom-checkbox` component that can both receive and update the parent's value.
+
+Crea un model signal en el componente `custom-checkbox` que pueda tanto recibir como actualizar el valor del padre.
```ts
-// Add imports for model signals
+// Agregar importaciones para model signals
import {Component, model, input, ChangeDetectionStrategy} from '@angular/core';
-// Model signal for two-way binding
+// Model signal para enlace bidireccional
checked = model.required();
-// Optional input for label
+// Input opcional para la etiqueta
label = input('');
```
-Unlike `input()` signals which are read-only, `model()` signals can be both read and written to.
+A diferencia de los signals `input()` que son de solo lectura, los signals `model()` pueden ser tanto leídos como escritos.
-
-Build the checkbox template that responds to clicks and updates its own model.
+
+Construye la plantilla del checkbox que responde a clics y actualiza su propio model.
```html
```
-The component reads from its model signal and has a method to update it.
+El componente lee de su model signal y tiene un método para actualizarlo.
-
-Implement the toggle method that updates the model signal when the checkbox is clicked.
+
+Implementa el método toggle que actualiza el model signal cuando se hace clic en el checkbox.
```ts
toggle() {
- // This updates BOTH the component's state AND the parent's model!
+ // ¡Esto actualiza TANTO el estado del componente COMO el model del padre!
this.checked.set(!this.checked());
}
```
-When the child component calls `this.checked.set()`, it automatically propagates the change back to the parent. This is the key difference from `input()` signals.
+Cuando el componente hijo llama a `this.checked.set()`, automáticamente propaga el cambio de vuelta al padre. Esta es la diferencia clave con los signals `input()`.
-
-First, uncomment the model signal properties and methods in `app.ts`:
+
+Primero, descomenta las propiedades y métodos de model signal en `app.ts`:
```ts
-// Parent signal models
+// Model signals del padre
agreedToTerms = model(false);
enableNotifications = model(true);
-// Methods to test two-way binding
+// Métodos para probar el enlace bidireccional
toggleTermsFromParent() {
this.agreedToTerms.set(!this.agreedToTerms());
}
@@ -74,14 +74,14 @@ resetAll() {
}
```
-Then update the template:
+Luego actualiza la plantilla:
-Part 1. **Uncomment the checkboxes and add two-way binding:**
+Parte 1. **Descomenta los checkboxes y agrega enlace bidireccional:**
-- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="agreedToTerms"` for the first checkbox
-- Replace `___ADD_TWO_WAY_BINDING___` with `[(checked)]="enableNotifications"` for the second
+- Reemplaza `___ADD_TWO_WAY_BINDING___` con `[(checked)]="agreedToTerms"` para el primer checkbox
+- Reemplaza `___ADD_TWO_WAY_BINDING___` con `[(checked)]="enableNotifications"` para el segundo
-Part 2. **Replace the `???` placeholders with @if blocks:**
+Parte 2. **Reemplaza los placeholders `???` con bloques @if:**
```angular-html
@if (agreedToTerms()) {
@@ -97,38 +97,38 @@ Part 2. **Replace the `???` placeholders with @if blocks:**
}
```
-Part 3. **Add click handlers to the buttons:**
+Parte 3. **Agrega manejadores de clic a los botones:**
```html
```
-The `[(checked)]` syntax creates two-way binding - data flows down to the component AND changes flow back up to the parent by emitting an event that references the signal itself and does _not_ call the signal getter directly.
+La sintaxis `[(checked)]` crea un enlace bidireccional — los datos fluyen hacia el componente Y los cambios fluyen de vuelta al padre emitiendo un evento que referencia el signal mismo y _no_ llama al getter del signal directamente.
-
-Interact with your app to see two-way binding in action:
+
+Interactúa con tu aplicación para ver el enlace bidireccional en acción:
-1. **Click checkboxes** - Component updates its own state and notifies parent
-2. **Click "Toggle Terms from Parent"** - Parent updates propagate down to component
-3. **Click "Reset All"** - Parent resets both models and components update automatically
+1. **Haz clic en los checkboxes** - El componente actualiza su propio estado y notifica al padre
+2. **Haz clic en "Toggle Terms from Parent"** - Las actualizaciones del padre se propagan al componente
+3. **Haz clic en "Reset All"** - El padre reinicia ambos models y los componentes se actualizan automáticamente
-Both the parent and child can update the shared state, and both stay in sync automatically!
+¡Tanto el padre como el hijo pueden actualizar el estado compartido, y ambos se mantienen sincronizados automáticamente!
-Perfect! You've learned how model signals enable two-way binding:
+¡Perfecto! Has aprendido cómo los model signals permiten el enlace bidireccional:
-- **Model signals** - Use `model()` and `model.required()` for values that can be both read and written
-- **Two-way binding** - Use `[(property)]` syntax to bind parent signals to child models
-- **Perfect for UI components** - Checkboxes, form controls, and widgets that need to manage their own state
-- **Automatic synchronization** - Parent and child stay in sync without manual event handling
+- **Model signals** - Usa `model()` y `model.required()` para valores que pueden ser tanto leídos como escritos
+- **Enlace bidireccional** - Usa la sintaxis `[(property)]` para enlazar signals del padre a models del hijo
+- **Perfecto para componentes de UI** - Checkboxes, controles de formulario y widgets que necesitan gestionar su propio estado
+- **Sincronización automática** - Padre e hijo se mantienen sincronizados sin manejo manual de eventos
-**When to use `model()` vs `input()`:**
+**Cuándo usar `model()` vs `input()`:**
-- Use `input()` for data that only flows down (display data, configuration)
-- Use `model()` for UI components that need to update their own value (form controls, toggles)
+- Usa `input()` para datos que solo fluyen hacia abajo (datos de visualización, configuración)
+- Usa `model()` para componentes de UI que necesitan actualizar su propio valor (controles de formulario, toggles)
-In the next lesson, you'll learn about [using signals with services](/tutorials/signals/7-using-signals-with-services)!
+En la próxima lección, aprenderás sobre [cómo usar signals con servicios](/tutorials/signals/7-using-signals-with-services)!
diff --git a/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md b/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md
new file mode 100644
index 0000000..15cc226
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.en.md
@@ -0,0 +1,103 @@
+# Using signals with services
+
+Now that you've learned [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals), let's explore how to use signals with Angular services. Services are perfect for sharing reactive state across multiple components, and signals make this even more powerful by providing automatic change detection and clean reactive patterns.
+
+In this activity, you'll learn how to create a cart store with signals that allow the cart display component to react to state changes automatically.
+
+
+
+
+
+
+Add readonly and computed signals to make the cart state reactive in `cart-store.ts`.
+
+```ts
+// Add the computed import
+import {Injectable, signal, computed} from '@angular/core';
+
+// Then add these signals to the class:
+
+// Readonly signals
+readonly cartItems = this.items.asReadonly();
+
+// Computed signals
+readonly totalQuantity = computed(() => {
+ return this.items().reduce((sum, item) => sum + item.quantity, 0);
+});
+
+readonly totalPrice = computed(() => {
+ return this.items().reduce((sum, item) => sum + item.price * item.quantity, 0);
+});
+```
+
+These signals allow components to reactively access cart data and computed totals. The `asReadonly()` method prevents external code from modifying the cart items directly, while `computed()` creates derived state that automatically updates when the source signal changes.
+
+
+
+The cart display component in `cart-display.ts` already uses the cart store signals in its template. Complete the quantity update methods to modify cart items:
+
+```ts
+increaseQuantity(id: string) {
+ const items = this.cartStore.cartItems();
+ const currentItem = items.find((item) => item.id === id);
+ if (currentItem) {
+ this.cartStore.updateQuantity(id, currentItem.quantity + 1);
+ }
+}
+
+decreaseQuantity(id: string) {
+ const items = this.cartStore.cartItems();
+ const currentItem = items.find((item) => item.id === id);
+ if (currentItem && currentItem.quantity > 1) {
+ this.cartStore.updateQuantity(id, currentItem.quantity - 1);
+ }
+}
+```
+
+These methods read the current cart state using `cartItems()` and update quantities through the store's methods. The UI automatically updates when the signals change!
+
+
+
+Update the main app component in `app.ts` to use the cart service and display the cart component.
+
+```angular-ts
+import {Component, inject} from '@angular/core';
+import {CartStore} from './cart-store';
+import {CartDisplay} from './cart-display';
+
+@Component({
+ selector: 'app-root',
+ imports: [CartDisplay],
+ template: `
+
+ `,
+ styleUrl: './app.css',
+})
+export class App {
+ cartStore = inject(CartStore);
+}
+```
+
+
+
+
+
+Excellent! You've now learned how to use signals with services. Key concepts to remember:
+
+- **Service-level signals**: Services can use signals to manage reactive state
+- **Dependency injection**: Use `inject()` to access services with signals in components
+- **Computed signals in services**: Create derived state that updates automatically
+- **Readonly signals**: Expose read-only versions of signals to prevent external mutations
+
+In the next lesson, you'll learn about [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives)!
diff --git a/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md b/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md
index 15cc226..f341f93 100644
--- a/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/7-using-signals-with-services/README.md
@@ -1,23 +1,23 @@
-# Using signals with services
+# Usando signals con servicios
-Now that you've learned [two-way binding with model signals](/tutorials/signals/6-two-way-binding-with-model-signals), let's explore how to use signals with Angular services. Services are perfect for sharing reactive state across multiple components, and signals make this even more powerful by providing automatic change detection and clean reactive patterns.
+Ahora que has aprendido [cómo usar el enlace bidireccional con model signals](/tutorials/signals/6-two-way-binding-with-model-signals), exploremos cómo usar signals con servicios de Angular. Los servicios son perfectos para compartir estado reactivo entre múltiples componentes, y los signals hacen esto aún más poderoso al proporcionar detección de cambios automática y patrones reactivos limpios.
-In this activity, you'll learn how to create a cart store with signals that allow the cart display component to react to state changes automatically.
+En esta actividad, aprenderás cómo crear un carrito de compras (cart store) con signals que permita que el componente de visualización del carrito reaccione a los cambios de estado automáticamente.
-
-Add readonly and computed signals to make the cart state reactive in `cart-store.ts`.
+
+Agrega signals de solo lectura y computed para hacer reactivo el estado del carrito en `cart-store.ts`.
```ts
-// Add the computed import
+// Agregar la importación de computed
import {Injectable, signal, computed} from '@angular/core';
-// Then add these signals to the class:
+// Luego agrega estos signals a la clase:
-// Readonly signals
+// Signals de solo lectura
readonly cartItems = this.items.asReadonly();
// Computed signals
@@ -30,11 +30,11 @@ readonly totalPrice = computed(() => {
});
```
-These signals allow components to reactively access cart data and computed totals. The `asReadonly()` method prevents external code from modifying the cart items directly, while `computed()` creates derived state that automatically updates when the source signal changes.
+Estos signals permiten a los componentes acceder reactivamente a los datos del carrito y los totales calculados. El método `asReadonly()` evita que código externo modifique los items del carrito directamente, mientras que `computed()` crea estado derivado que se actualiza automáticamente cuando el signal fuente cambia.
-
-The cart display component in `cart-display.ts` already uses the cart store signals in its template. Complete the quantity update methods to modify cart items:
+
+El componente de visualización del carrito en `cart-display.ts` ya usa los signals del cart store en su plantilla. Completa los métodos de actualización de cantidad para modificar los items del carrito:
```ts
increaseQuantity(id: string) {
@@ -54,11 +54,11 @@ decreaseQuantity(id: string) {
}
```
-These methods read the current cart state using `cartItems()` and update quantities through the store's methods. The UI automatically updates when the signals change!
+Estos métodos leen el estado actual del carrito usando `cartItems()` y actualizan las cantidades a través de los métodos del store. ¡La UI se actualiza automáticamente cuando los signals cambian!
-
-Update the main app component in `app.ts` to use the cart service and display the cart component.
+
+Actualiza el componente principal de la app en `app.ts` para usar el servicio del carrito y mostrar el componente del carrito.
```angular-ts
import {Component, inject} from '@angular/core';
@@ -93,11 +93,11 @@ export class App {
-Excellent! You've now learned how to use signals with services. Key concepts to remember:
+¡Excelente! Ahora has aprendido cómo usar signals con servicios. Conceptos clave para recordar:
-- **Service-level signals**: Services can use signals to manage reactive state
-- **Dependency injection**: Use `inject()` to access services with signals in components
-- **Computed signals in services**: Create derived state that updates automatically
-- **Readonly signals**: Expose read-only versions of signals to prevent external mutations
+- **Signals a nivel de servicio**: Los servicios pueden usar signals para gestionar estado reactivo
+- **Inyección de dependencias**: Usa `inject()` para acceder a servicios con signals en componentes
+- **Computed signals en servicios**: Crea estado derivado que se actualiza automáticamente
+- **Signals de solo lectura**: Expone versiones de solo lectura de los signals para prevenir mutaciones externas
-In the next lesson, you'll learn about [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives)!
+En la próxima lección, aprenderás sobre [cómo usar signals con directivas](/tutorials/signals/8-using-signals-with-directives)!
diff --git a/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md b/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md
new file mode 100644
index 0000000..5f6dba3
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.en.md
@@ -0,0 +1,110 @@
+# Using signals with directives
+
+Now that you've learned [using signals with services](/tutorials/signals/7-using-signals-with-services), let's explore how directives use signals. **The great news: signals work exactly the same in directives as they do in components!** The main difference is that since directives don't have templates, you'll primarily use signals in host bindings to reactively update the host element.
+
+In this activity, you'll build a highlight directive that demonstrates how signals create reactive behavior in directives.
+
+
+
+
+
+
+Import the signal functions and create your reactive state. This works exactly the same as in components:
+
+```ts
+import {Directive, input, signal, computed} from '@angular/core';
+
+@Directive({
+ selector: '[highlight]',
+})
+export class HighlightDirective {
+ // Signal inputs - same as components!
+ color = input('yellow');
+ intensity = input(0.3);
+
+ // Internal state - same as components!
+ private isHovered = signal(false);
+
+ // Computed signals - same as components!
+ backgroundStyle = computed(() => {
+ const baseColor = this.color();
+ const alpha = this.isHovered() ? this.intensity() : this.intensity() * 0.5;
+
+ const colorMap: Record = {
+ 'yellow': `rgba(255, 255, 0, ${alpha})`,
+ 'blue': `rgba(0, 100, 255, ${alpha})`,
+ 'green': `rgba(0, 200, 0, ${alpha})`,
+ 'red': `rgba(255, 0, 0, ${alpha})`,
+ };
+
+ return colorMap[baseColor] || colorMap['yellow'];
+ });
+}
+```
+
+Notice how this is identical to component patterns - the only difference is we're in a `@Directive` instead of `@Component`.
+
+
+
+Since directives don't have templates, you'll use signals in **host bindings** to reactively update the host element. Add the `host` configuration and event handlers:
+
+```ts
+@Directive({
+ selector: '[highlight]',
+ host: {
+ '[style.backgroundColor]': 'backgroundStyle()',
+ '(mouseenter)': 'onMouseEnter()',
+ '(mouseleave)': 'onMouseLeave()',
+ },
+})
+export class HighlightDirective {
+ // ... signals from previous step ...
+
+ onMouseEnter() {
+ this.isHovered.set(true);
+ }
+
+ onMouseLeave() {
+ this.isHovered.set(false);
+ }
+}
+```
+
+The host bindings automatically re-evaluate when the signals change - just like template bindings in components! When `isHovered` changes, the `backgroundStyle` computed signal recalculates, and the host binding updates the element's style.
+
+
+
+Update the app template to demonstrate the reactive directive:
+
+```angular-ts
+template: `
+
+
Directive with Signals
+
+
+ Hover me - Yellow highlight
+
+
+
+ Hover me - Blue highlight
+
+
+
+ Hover me - Green highlight
+
+
+`,
+```
+
+The directive automatically applies reactive highlighting based on the signal inputs!
+
+
+
+
+Perfect! You've now seen how signals work with directives. Some key takeaways from this lesson are:
+
+- **Signals are universal** - All signal APIs (`input()`, `signal()`, `computed()`, `effect()`) work the same in both directives and components
+- **Host bindings are the primary use case** - Since directives don't have templates, you use signals in host bindings to reactively modify the host element
+- **Same reactive patterns** - Signal updates trigger automatic re-evaluation of computed signals and host bindings, just like in component templates
+
+In the next lesson, you'll [learn how to query child elements with signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries)!
diff --git a/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md b/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md
index 5f6dba3..b9a0f0f 100644
--- a/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/8-using-signals-with-directives/README.md
@@ -1,15 +1,15 @@
-# Using signals with directives
+# Usando signals con directivas
-Now that you've learned [using signals with services](/tutorials/signals/7-using-signals-with-services), let's explore how directives use signals. **The great news: signals work exactly the same in directives as they do in components!** The main difference is that since directives don't have templates, you'll primarily use signals in host bindings to reactively update the host element.
+Ahora que has aprendido [cómo usar signals con servicios](/tutorials/signals/7-using-signals-with-services), exploremos cómo las directivas usan signals. **La buena noticia: los signals funcionan exactamente igual en directivas que en componentes.** La diferencia principal es que, como las directivas no tienen plantillas, usarás principalmente signals en host bindings para actualizar reactivamente el elemento host.
-In this activity, you'll build a highlight directive that demonstrates how signals create reactive behavior in directives.
+En esta actividad, construirás una directiva de resaltado que demuestra cómo los signals crean comportamiento reactivo en directivas.
-
-Import the signal functions and create your reactive state. This works exactly the same as in components:
+
+Importa las funciones de signal y crea tu estado reactivo. Esto funciona exactamente igual que en componentes:
```ts
import {Directive, input, signal, computed} from '@angular/core';
@@ -18,14 +18,14 @@ import {Directive, input, signal, computed} from '@angular/core';
selector: '[highlight]',
})
export class HighlightDirective {
- // Signal inputs - same as components!
+ // Signal inputs - ¡igual que en componentes!
color = input('yellow');
intensity = input(0.3);
- // Internal state - same as components!
+ // Estado interno - ¡igual que en componentes!
private isHovered = signal(false);
- // Computed signals - same as components!
+ // Computed signals - ¡igual que en componentes!
backgroundStyle = computed(() => {
const baseColor = this.color();
const alpha = this.isHovered() ? this.intensity() : this.intensity() * 0.5;
@@ -42,11 +42,11 @@ export class HighlightDirective {
}
```
-Notice how this is identical to component patterns - the only difference is we're in a `@Directive` instead of `@Component`.
+Observa cómo esto es idéntico a los patrones de componentes — la única diferencia es que estamos en una `@Directive` en lugar de `@Component`.
-
-Since directives don't have templates, you'll use signals in **host bindings** to reactively update the host element. Add the `host` configuration and event handlers:
+
+Como las directivas no tienen plantillas, usarás signals en **host bindings** para actualizar reactivamente el elemento host. Agrega la configuración `host` y los manejadores de eventos:
```ts
@Directive({
@@ -58,7 +58,7 @@ Since directives don't have templates, you'll use signals in **host bindings** t
},
})
export class HighlightDirective {
- // ... signals from previous step ...
+ // ... signals del paso anterior ...
onMouseEnter() {
this.isHovered.set(true);
@@ -70,11 +70,11 @@ export class HighlightDirective {
}
```
-The host bindings automatically re-evaluate when the signals change - just like template bindings in components! When `isHovered` changes, the `backgroundStyle` computed signal recalculates, and the host binding updates the element's style.
+Los host bindings se re-evalúan automáticamente cuando los signals cambian — ¡igual que los enlaces de plantilla en componentes! Cuando `isHovered` cambia, el computed signal `backgroundStyle` se recalcula y el host binding actualiza el estilo del elemento.
-
-Update the app template to demonstrate the reactive directive:
+
+Actualiza la plantilla de la app para demostrar la directiva reactiva:
```angular-ts
template: `
@@ -96,15 +96,15 @@ template: `
`,
```
-The directive automatically applies reactive highlighting based on the signal inputs!
+¡La directiva aplica automáticamente el resaltado reactivo basado en los signal inputs!
-Perfect! You've now seen how signals work with directives. Some key takeaways from this lesson are:
+¡Perfecto! Ahora has visto cómo funcionan los signals con directivas. Algunos puntos clave de esta lección:
-- **Signals are universal** - All signal APIs (`input()`, `signal()`, `computed()`, `effect()`) work the same in both directives and components
-- **Host bindings are the primary use case** - Since directives don't have templates, you use signals in host bindings to reactively modify the host element
-- **Same reactive patterns** - Signal updates trigger automatic re-evaluation of computed signals and host bindings, just like in component templates
+- **Los signals son universales** - Todas las APIs de signal (`input()`, `signal()`, `computed()`, `effect()`) funcionan igual en directivas y componentes
+- **Los host bindings son el caso de uso principal** - Como las directivas no tienen plantillas, usas signals en host bindings para modificar reactivamente el elemento host
+- **Mismos patrones reactivos** - Las actualizaciones de signals disparan la re-evaluación automática de computed signals y host bindings, igual que en las plantillas de componentes
-In the next lesson, you'll [learn how to query child elements with signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries)!
+En la próxima lección, [aprenderás cómo consultar elementos hijos con signal queries](/tutorials/signals/9-query-child-elements-with-signal-queries)!
diff --git a/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md b/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md
new file mode 100644
index 0000000..8354746
--- /dev/null
+++ b/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.en.md
@@ -0,0 +1,66 @@
+# Query child elements with signal queries
+
+Now that you've learned [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives), let's explore signal-based query APIs. These provide a reactive way to access and interact with child components and directives. Both components and directives can perform queries while also being queried themselves. Unlike the traditional ViewChild, signal queries automatically update and provide type-safe access to child components and directives.
+
+In this activity, you'll add viewChild queries to interact with child components programmatically.
+
+
+
+
+
+
+First, add the `viewChild` import to access child components in `app.ts`.
+
+```ts
+import {Component, signal, computed, viewChild, ChangeDetectionStrategy} from '@angular/core';
+```
+
+
+
+
+Add viewChild queries to the App component to access child components.
+
+```ts
+// Query APIs to access child components
+firstProduct = viewChild(ProductCard);
+cartSummary = viewChild(CartSummary);
+```
+
+These queries create signals that reference child component instances.
+
+
+
+Use the viewChild queries to call methods on child components in `app.ts`:
+
+```ts
+showFirstProductDetails() {
+ const product = this.firstProduct();
+ if (product) {
+ product.highlight();
+ }
+}
+
+initiateCheckout() {
+ const summary = this.cartSummary();
+ if (summary) {
+ summary.initiateCheckout();
+ }
+}
+```
+
+
+
+
+The control buttons should now work:
+
+- **"Show First Product Details"** - Calls `highlight()` on the ProductCard
+- **"Initiate Checkout"** - Calls `initiateCheckout()` on the CartSummary
+
+Click the buttons to see how viewChild queries enable parent components to control child behavior.
+
+
+
+
+Perfect! You've learned how to use signal-based query APIs for child component interaction:
+
+In the next lesson, you'll learn about [how to react to signal changes with effect](/tutorials/signals/10-reacting-to-signal-changes-with-effect)!
diff --git a/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md b/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md
index 8354746..00fee5c 100644
--- a/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md
+++ b/adev-es/src/content/tutorials/signals/steps/9-query-child-elements-with-signal-queries/README.md
@@ -1,15 +1,15 @@
-# Query child elements with signal queries
+# Consulta elementos hijos con signal queries
-Now that you've learned [how to use signals with directives](/tutorials/signals/8-using-signals-with-directives), let's explore signal-based query APIs. These provide a reactive way to access and interact with child components and directives. Both components and directives can perform queries while also being queried themselves. Unlike the traditional ViewChild, signal queries automatically update and provide type-safe access to child components and directives.
+Ahora que has aprendido [cómo usar signals con directivas](/tutorials/signals/8-using-signals-with-directives), exploremos las APIs de consulta basadas en signals. Estas proporcionan una forma reactiva de acceder e interactuar con componentes y directivas hijos. Tanto los componentes como las directivas pueden realizar consultas mientras también pueden ser consultados ellos mismos. A diferencia del tradicional ViewChild, las signal queries se actualizan automáticamente y proporcionan acceso seguro con tipos a componentes y directivas hijos.
-In this activity, you'll add viewChild queries to interact with child components programmatically.
+En esta actividad, agregarás consultas viewChild para interactuar con componentes hijos programáticamente.
-
-First, add the `viewChild` import to access child components in `app.ts`.
+
+Primero, agrega la importación de `viewChild` para acceder a componentes hijos en `app.ts`.
```ts
import {Component, signal, computed, viewChild, ChangeDetectionStrategy} from '@angular/core';
@@ -17,20 +17,20 @@ import {Component, signal, computed, viewChild, ChangeDetectionStrategy} from '@
-
-Add viewChild queries to the App component to access child components.
+
+Agrega consultas viewChild al componente App para acceder a componentes hijos.
```ts
-// Query APIs to access child components
+// APIs de consulta para acceder a componentes hijos
firstProduct = viewChild(ProductCard);
cartSummary = viewChild(CartSummary);
```
-These queries create signals that reference child component instances.
+Estas consultas crean signals que referencian instancias de componentes hijos.
-
-Use the viewChild queries to call methods on child components in `app.ts`:
+
+Usa las consultas viewChild para llamar métodos en componentes hijos en `app.ts`:
```ts
showFirstProductDetails() {
@@ -50,17 +50,17 @@ initiateCheckout() {
-
-The control buttons should now work:
+
+Los botones de control ahora deberían funcionar:
-- **"Show First Product Details"** - Calls `highlight()` on the ProductCard
-- **"Initiate Checkout"** - Calls `initiateCheckout()` on the CartSummary
+- **"Show First Product Details"** - Llama a `highlight()` en el ProductCard
+- **"Initiate Checkout"** - Llama a `initiateCheckout()` en el CartSummary
-Click the buttons to see how viewChild queries enable parent components to control child behavior.
+Haz clic en los botones para ver cómo las consultas viewChild permiten que los componentes padre controlen el comportamiento de los hijos.
-Perfect! You've learned how to use signal-based query APIs for child component interaction:
+¡Perfecto! Has aprendido cómo usar las APIs de consulta basadas en signals para la interacción con componentes hijos.
-In the next lesson, you'll learn about [how to react to signal changes with effect](/tutorials/signals/10-reacting-to-signal-changes-with-effect)!
+En la próxima lección, aprenderás sobre [cómo reaccionar a cambios de signal con effect](/tutorials/signals/10-reacting-to-signal-changes-with-effect)!