WhatsApp

  
Angular v16 ¡está aquí!

Replanteando la Reactividad

Como parte de la versión 16, estamos emocionados de compartir una vista previa para desarrolladores de un nuevo modelo de reactividad para Angular, que aporta mejoras significativas en el rendimiento y la experiencia del desarrollador.

Es completamente compatible hacia atrás e interoperable con el sistema actual, y habilita:

  • Mejor rendimiento en tiempo de ejecución al reducir la cantidad de cálculos durante la detección de cambios. Una vez que se implementen completamente las Señales de Angular, esperamos mejoras significativas en la métrica INP Core Web Vital para las aplicaciones construidas con señales.
  • Introduce un modelo mental más simple para la reactividad, dejando claro cuáles son las dependencias de la vista y cuál es el flujo de datos en la aplicación.
  • Permite una reactividad detallada que, en futuras versiones, nos permitirá verificar cambios solo en los componentes afectados.
  • Hace que Zone.js sea opcional en futuras versiones al utilizar señales para notificar al marco cuando el modelo ha cambiado.
  • Ofrece propiedades calculadas sin la penalización de la recomputación en cada ciclo de detección de cambios.
  • Facilita una mejor interoperabilidad con RxJS al esbozar un plan para introducir entradas reactivas.

La discusión inicial en GitHub generó 682 comentarios, y desde entonces, compartimos una serie de RFC que recibieron más de 1,000 comentarios adicionales.

En la versión 16, encontrarás una nueva biblioteca de señales que forma parte de @angular/core y un paquete de interoperabilidad con RxJS: @angular/core/rxjs-interop. La integración completa de señales en el marco se lanzará más adelante este año.

Señales de Angular
La biblioteca de señales de Angular te permite definir valores reactivos y expresar dependencias entre ellos. Puedes obtener más información sobre las propiedades de la biblioteca en el RFC correspondiente. Aquí tienes un ejemplo sencillo de cómo usarla con Angular:

@Component({
selector: 'my-app',
standalone: true,
template: `
{{ fullName() }} <button (click)="setName('John')">Click</button>
`,
})
export class App {
firstName = signal('Jane');
lastName = signal('Doe');
fullName = computed(() => `${this.firstName()} ${this.lastName()}`);

constructor() {
effect(() => console.log('Name changed:', this.fullName()));
}

setName(newName: string) {
this.firstName.set(newName);
}
}

El fragmento anterior crea un valor calculado llamado fullName, que depende de las señales firstName y lastName. También declaramos un efecto cuya función de retorno se ejecutará cada vez que cambie el valor de cualquiera de las señales que lee; en este caso, fullName. Esto significa que de manera transitoria también depende de firstName y lastName.

Cuando establecemos el valor de firstName en "John", el navegador registrará en la consola:

"Name changed: John Doe"

Interoperabilidad con RxJS Podrás convertir fácilmente señales en observables mediante las funciones de @angular/core/rxjs-interop, que se encuentran en vista previa para desarrolladores como parte de la versión 16.

Así es cómo puedes convertir una señal en un observable:

import { toObservable } from '@angular/core/rxjs-interop';

@Component({...})
export class App {
count = signal(0);
count$ = toObservable(this.count);

ngOnInit() {
this.count$.subscribe(() => ...);
}
}

...y aquí tienes un ejemplo de cómo puedes convertir un observable en señal para evitar usar async pipe:

import {toSignal} from '@angular/core/rxjs-interop';

@Component({
template: `
<li *ngFor="let row of data()"> {{ row }} </li>
`
})
export class App {
dataService = inject(DataService);
data = toSignal(this.dataService.data$, []);
}

Los usuarios de Angular a menudo desean completar un flujo cuando un tema relacionado se completa. El siguiente patrón ilustrativo es bastante común:

destroyed$ = new ReplaySubject<void>(1);

data$ = http.get('...').pipe(takeUntil(this.destroyed$));

ngOnDestroy() {
this.destroyed$.next();
}

Estamos introduciendo un nuevo operador RxJS llamado takeUntilDestroyed, que simplifica este ejemplo de la siguiente manera:

data$ = http.get('…').pipe(takeUntilDestroyed());

Por defecto, este operador inyectará el contexto de limpieza actual. Por ejemplo, si se usa en un componente, utilizará el ciclo de vida del componente.

takeUntilDestroyed es especialmente útil cuando deseas vincular el ciclo de vida de un Observable al ciclo de vida de un componente específico.

Próximos pasos para las señales

A continuación, trabajaremos en componentes basados en señales que tendrán un conjunto simplificado de ganchos de ciclo de vida y una forma alternativa y más sencilla de declarar entradas y salidas. También trabajaremos en un conjunto más completo de ejemplos y documentación.

Uno de los problemas más populares en el repositorio de Angular es "Propuesta: Input como Observable". Hace un par de meses, respondimos que queremos respaldar este caso de uso como parte de un esfuerzo más amplio en el marco. Nos complace compartir que más adelante este año implementaremos una función que permitirá entradas basadas en señales. ¡Podrás transformar las entradas en observables a través del paquete de interoperabilidad!

"Blog citado: Angular v16 is here!"

Minko Gechev. (2023). Angular v16 is here! Angular Blog. [https://blog.angular.io/angular-v16-is-here-4d7a28ec680d]


Compartir


Angular v16 ¡está aquí!
Mario Molina 30 septiembre, 2023
Compartir
Categorías


Iniciar sesión dejar un comentario

  
Implementación de AuthGuard para Definir Permisos de Acceso en Angular