Resumen de las novedades de Angular 20
· 20 min · linux
Introducción
El equipo de Angular ha lanzado la versión 20 de este popular framework el día 28 de mayo de 2025. Desde el blog oficial de Angular
Highlights
- Consideradas Obsoletas las directivas NgIf, NgFor, and NgSwitch, el ng update permite realizar la migración de las antiguas directivas a usar el nuevo control flow.
- Se han estabilizado los APIS de effect, linkedSignal, toSignal, hidratación incremental, route-level render mode config (SSR).
- Se ha colocado en developer preview el sistema Zoneless.
- Se han mejorado las Angular DevTools y su integración con las Chrome DevTools.
- Se ha mejorado la experiencia de desarrollo con actualizaciones de las guías de estilos, comprobaciones de tipos y soporte de host bindings en el language service para los editors, soporte para un nuevo sistema de uso de expresiones en las plantillas con interpolaciones, y la carga de tipo Hot module por defecto.
- Se ha colocado un nuevo fichero llamado llms.txt y nuevas guías y vídeos para del desarrollo de aplicaciones GeanAI.
- Se han lanzado una serie de propuestas para la mascota oficial de Angular.
- Se han eliminado los nombres de elementos de la arquitectura de Angular, de los nombres de los ficheros, por ejemplo el fichero del componente principal de la aplicación ahora se llamará app.ts
Signals
Angular 20 ha introducido una serie de mejoras en el sistema de Signals, que permiten una reactividad más eficiente y flexible en las aplicaciones Angular. Algunas de las mejoras incluyen:
- linkedSignal: Permite vincular señales entre diferentes componentes, facilitando la comunicación y la sincronización de estados.
- toSignal: Proporciona una forma de convertir observables en señales, lo que permite una integración más fluida con el sistema de reactividad de Angular.
- *effect: Permite crear efectos secundarios que se ejecutan en respuesta a cambios en las señales, lo que facilita la gestión de side effects en las aplicaciones.
Effects
Siempre que tengas que ejecutar un método asociado al cambio de un valor de una o más señales, puedes usar el efecto effect
para ejecutar un código que dependa de una o más señales. Por ejemplo, si tienes una señal count
y quieres ejecutar un efecto cada vez que cambie, puedes hacerlo de la siguiente manera:
import { effect, signal } from '@angular/core'
@Component({
selector: 'app-signals20',
imports: [],
templateUrl: './signals20.html',
styleUrl: './signals20.css'
})
export class Signals20 implements OnDestroy {
count: WritableSignal<number> = signal(0)
// en teoría se autodestruye al salir del componente, pero se puede destruir manualmente en el OnDestroy
retEffect: EffectRef
constructor() {
// Sólo de ejecuta de manera asíncrona una vez por cambio de señal
this.retEffect = effect(() => {
console.log(`The current count is: ${this.count()}`)
})
}
ngOnDestroy(): void {
this.retEffect.destroy()
}
increment() {
this.count.update((value) => {
return value + 1
})
}
}
Fichero de la plantilla signals20.html
:
<div>
<h2>Signals</h2>
<h3>{{count()}}</h3>
<button class="btn btn-success" (click)="increment()">Increment</button>
</div>
Como vemos podemos usar la función effect y asociamos una función que se ejecutará cada vez que cambie el valor de la señal count
. En este caso, simplemente imprimimos el valor actual de count
en la consola.
Por defecto, el efecto se ejecuta de manera asíncrona, lo que significa que no bloquea la ejecución del código y permite que la aplicación siga funcionando mientras se actualiza el valor de la señal.
Además podemos destruir el efecto manualmente en el método ngOnDestroy
del componente, aunque en teoría se destruye automáticamente al salir del componente.
linkedSignal
Es un tipo señal parecida a la computed, pero que permite cambiar su valor en el caso de ser necesario. Si se actualiza el valor de la señal original, se actualiza automáticamente el valor de la linkedSignal.
import { Component, linkedSignal, signal, WritableSignal } from '@angular/core'
@Component({
selector: 'app-linked-signal',
imports: [],
templateUrl: './linked-signal.html',
styleUrl: './linked-signal.css'
})
export class LinkedSignalComponent {
// señal original
options: WritableSignal<string[]> = signal(['A', 'B', 'C'])
// linkedSignal
linkedSignal: WritableSignal<string> = linkedSignal(() => this.options()[0])
cambiaLinked() {
this.linkedSignal.update((value) => {
return `${value}!`
})
}
cambiaSenal() {
this.options.set(['a', 'b', 'c', 'd'])
}
}
Ahora el código de la plantilla linked-signal.html
:
<h2>LinkedSignal</h2>
<h3>options: {{options() | json}}</h3>
<h3>linkedSignal: {{linkedSignal()}}</h3>
<button class="btn btn-success" (click)="cambiaLinked()">Cambia LinkedSignal</button>
<button class="btn btn-success" (click)="cambiaSenal()">Cambia Señal original</button>
toSignal
Para crear señales en base a observables, podemos usar la función toSignal
. Esta función permite convertir un observable en una señal, lo que facilita la integración de observables en el nuevo sistema de reactividad de Angular.
import { toSignal } from '@angular/core/rxjs-interop'
import { interval } from 'rxjs'
@Component({
template: `{{ counter() }}`,
})
export class Ticker {
counterObservable = interval(1000)
// Get a `Signal` representing the `counterObservable`'s value.
counter = toSignal(this.counterObservable, { initialValue: 0 })
}
En este ejemplo, toSignal
convierte el observable counterObservable
en una señal counter
, que se actualiza cada segundo con el valor emitido por el observable. El parámetro initialValue
se utiliza para establecer un valor inicial para la señal.
Hidratación incremental
- Se ha pasado a estable el sistema de hidratación incremental, que permite que las aplicaciones Angular se carguen más rápido y de manera más eficiente. Este sistema permite que las aplicaciones se hidraten de manera incremental, lo que significa que solo se cargan los componentes necesarios en el momento adecuado, en lugar de cargar toda la aplicación de una vez.
- Se ha mejorado el soporte de las Chrome DevTools para la depuración de la hidratación incremental, lo que facilita a los desarrolladores identificar y solucionar problemas relacionados con la hidratación de sus componentes.
Configuración del modo de renderizado a nivel de ruta (SSR)
Angular 20 ha introducido una nueva forma de configurar el modo de renderizado a nivel de ruta para las aplicaciones que utilizan Server-Side Rendering (SSR). Esta característica permite a los desarrolladores especificar cómo se deben renderizar las rutas en el servidor, lo que puede mejorar el rendimiento y la experiencia del usuario, y la manera de renderizar los componentes dependiendo de cómo se configure.
export const routeConfig: ServerRoute = [
{ path: '/login', mode: RenderMode.Server },
{ path: '/dashboard', mode: RenderMode.Client },
{
path: '/product/:id',
mode: RenderMode.Prerender,
async getPrerenderParams() {
const dataService = inject(ProductService)
const ids = await dataService.getIds() // ["1", "2", "3"]
// `id` is used in place of `:id` in the route path.
return ids.map(id => ({ id }))
}
}
]
En este ejemplo, se define una configuración de ruta que especifica el modo de renderizado para cada ruta. La ruta /login
se renderiza en el servidor, la ruta /dashboard
se renderiza en el cliente y la ruta /product/:id
se prerenderiza con parámetros específicos.
Mejorada la experiencia de desarrollo
Angular 20 ha mejorado la experiencia de desarrollo con una serie de actualizaciones y mejoras en las herramientas y guías de estilo. Algunas de las mejoras incluyen:
- Perfiles de rendimiento para las Angular DevTools, que permiten a los desarrolladores analizar y optimizar el rendimiento de sus aplicaciones. Para que funcione podemos ejecutar, por ejemplo desde la consola de Chrome: ng.enableProfiling()
- Se ha metido un nuevo método llamada createComponent que permite crear componentes de manera programática, lo que facilita la creación de componentes dinámicos, que por ejemplo podrían ser instanciados desde un servicio. En Angular 20 se ha añadido la posibilidad de asociar directivas y bindings. Esta función podría llegar a ser últil a la hora de cargar modales.
- Se ha ampliado la sintaxis de las expresiones en las plantillas, permitiendo desde la versión 20 el uso de los operadores ** para pa potencia, y el operador in para comprobar si existe una propiedad dentro de un objeto.
<!-- n on power two -->
{{ n ** 2 }}
<!-- checks if the person object contains the name property -->
{{ name in person }}
- También se ha metido la posibilidad de usar interpolaciones dentro de las expresiones, lo que permite una mayor flexibilidad en la creación de plantillas.
<div [class]="`layout col-${colWidth}`"></div>
- Se han mejorado los diagnósticos de ciertos errores en las plantillas, como por ejemplo el uso de track en los @for
- Se han actualizado las guías de estilo para reflejar las mejores prácticas y recomendaciones más recientes, lo que facilita a los desarrolladores seguir las convenciones de Angular. Desde v cada vez que generamos un nuevo componente ya tanto el nomrbe de ficheros como el nombre del componente no tendrán el sufijo .component y Component.
- Esto se ha aplicado también a las directivas, pipes, guard, interceptor, module, resolver y servicios.
- Se ha mejorado el soporte de host bindings en el language service para los editores, lo que facilita la creación y edición de componentes con host bindings.
- Se ha metido un soporte experimental para vitest, para meter pruebas de navegador de nuestra aplicación como alternativa al Karma que está obsoleto.
- Mejorados de calidad de vida de Angular Material, como los botones par acercarlos a la definición de Material 3.
API’s Experimentales
Se ha metido un API nuevo con la idea de manejar recursos de manera reactiva con señales. La idea es por ejemplo asociar una petición HTTP al cambio de una señal, de manera que cuando cambie el valor de la señal, se realice una nueva petición HTTP. Y que devuelva el dato como otra señal.
const userId: Signal<string> = getUserId()
const userResource = resource({
params: () => ({ id: userId() }),
loader: ({ request, abortSignal }): Promise<User> => {
// fetch cancels any outstanding HTTP requests when the given `AbortSignal`
// indicates that the request has been aborted.
return fetch(`users/${request.id}`, { signal: abortSignal })
},
})
También se podría pedir datos por streaming vía Websocket.
Ayuda a la GenAI
- De cara a ayudar al entrenamiento de los modelos de GenAI, a la hora de generar código angular, se ha metido un fichero llamado
llms.txt
que contiene una serie de guías y vídeos para el desarrollo de aplicaciones GenAI. Este fichero se puede utilizar para mejorar la calidad y la precisión de los modelos de GenAI, lo que puede ayudar a mejorar la experiencia del usuario en las aplicaciones Angular. - Han hecho mucha promo para que la gente que haga interfaces de Aplicaciones Frontend con Angular de aplicaciones GenAI.
NgIf, NgFor, and NgSwitch obsoletas
A partir de Angular 20, las directivas NgIf
, NgFor
y NgSwitch
se consideran obsoletas. En su lugar, se recomienda utilizar el nuevo control flow, que ofrece una forma más eficiente y flexible de manejar la lógica de control de flujo en las plantillas.
Cuando actualizamos las aplicaciones con ng update
, se nos ofrece la posibilidad de migrar automáticamente las directivas obsoletas a usar el nuevo control flow.
Si quieres ejecutarlo fuera del proceso de update puedes ejecutar el siguiente comando:
ng generate @angular/core:control-flow
Esto significa que para la v22 estarán eliminadas y no se podrán usar, por lo que es recomendable migrar a las nuevas directivas cuanto antes.
Nueva mascota de Angular
El equipo de Angular ha lanzado una serie de propuestas para la nueva mascota oficial de Angular. Estas propuestas incluyen una variedad de diseños y conceptos que reflejan la identidad y los valores de Angular. La comunidad está invitada a participar en la votación para elegir la nueva mascota oficial.
Conclusión
Angular 20 trae una serie de mejoras y nuevas características que mejoran la experiencia de desarrollo y el rendimiento de las aplicaciones Angular. Desde la introducción de nuevas APIs experimentales hasta la mejora de las herramientas de desarrollo, Angular 20 es una actualización significativa que vale la pena explorar.