WcfSubcomps: modificar los componentes en tiempo de ejecución – Angular

Los componentes generados por WCF cumplen con los estándares y especificaciones de Angular, y están generados de modo de que su código sea completamente legible. Esto permite que se comporten en tiempo de ejecución tal como se espera y se puedan utilizar agregando el código necesario, como si el componente hubiera sido creado como parte del proyecto.

Sumado a eso, y sin interferir en ello, WCF provee un injectable service que permite modificar en tiempo de ejecución cualquiera de los atributos y parámetros del componente1. Para conocer en detalle los atributos y parámetros, basta con acceder a la app-demo del componente.

Por qué un servicio adicional

En Angular y en otras plataformas de componentes es natural y fluida la interacción en tiempo real con los datos del componente y sus antecesores y descendientes de primer nivel. Pero cuando la relación es profunda o cuando los componentes pertenecen a ramas distintas la comunicación entre componentes se hace compleja.

Ese es uno de los objetivos de los servicios inyectables: permitir una comunicación fluida independientemente de la estructura de creación e inclusión de componentes en la aplicación.

WCF sigue esta línea y aporta un servicio muy liviano (no llega a las 100 líneas de código) que permite modificar todos los inputs y atributos de un componente desde cualquier parte de la aplicación. A esto suma que no se necesita agregar código adicional a los componentes para utilizarlo y de que a pesar de que viene con cada componente, está diseñado siguiendo el pattern de tree-shaking, de modo de que se incluye una sola vez en el código independientemente de la cantidad de componentes que lo incluyan.

Independizarse del proceso de rendering

El servicio WcfSubcomps incluye una cola de mensajes que espera que cada componente se “renderice” en la pantalla antes de enviar sus mensajes, de modo de que estos no se pierdan. Esto hace muy fácil determinar programáticamente los valores por omisión y otros valores, que muchas veces dependen de servicios externos y es difícil sincronizar con el despliegue en pantalla.

En combinación con la opción de que el default del componente no incluya ni textos ni imagenes, los componentes se desplegarán en la pantalla en su tamaño original y con los textos correctos, o con placeholders vacíos.

Utilizando WcfSubcomps

Para utilizar el servicio en cualquier parte de una aplicación Angular, hay que importarlo, declarar una propiedad, inicializarla y luego invocarlo. Lo mostramos en un ejemplo2.

  1. Cree una nueva aplicación y ejecute la app-demo de un componente, tal como se indica en el artículo correspondiente.
  2. Abra para editar el archivo src/app/app.component.ts
  3. Debajo de la primera linea, que importa Component, agregue otra que importa Subscription
import { Component } from '@angular/core';
import { Subscription } from "rxjs";
  1. En la clase exportable, agregue la inicialización del servicio
export class AppComponent {
	title = 'app-demo';

	wcfSubcompsSubscription: Subscription;

	constructor(private wcfSubcompsService: WcfSubcomps) {
		this.wcfSubcompsSubscription = Subscription.EMPTY;
}
  1. Ahora ya se puede enviar mensajes a cualquiera de los componentes. Como ejemplo utilizaremos el hook ngAfterViewInit para cambiar los valores en el momento de la inicialización.
    Asumimos que su id es bloque-pestanas y que tiene un switch denominado consultas. Tiene también un subcomponente, con id enlace-volver, al que se le puede cambiar el texto usando el atributo texto_enlace.
    De esta forma se puede cambiar cualquier atributo o propiedad del componente principal y su subcomponentes. Para conocer en detalle los subcomponentes, los atributos y las propiedades, alcanza con consultar la app-demo
ngAfterViewInit () {
	this.wcfSubcompsService.changeAttribute({"id":"bloque-pestanas", "consultas":"off"});
	this.wcfSubcompsService.changeAttribute({"id":"bloque-pestanas.enlace-volver", "texto_enlace":"Nuevo texto del enlace"});
}

El código completo de src/app/app.component.ts quedaría así:

import { Component } from '@angular/core';
import { Subscription } from "rxjs";

import { WcfSubcomps } from "./wcf-subcomps/wcf-subcomps.service";
import { BloquePestanas } from "./bloque-pestanas/bloque-pestanas.component";

import { AppDemo } from "./app-demo-bloque-pestanas/app-demo.component";

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [BloquePestanas, AppDemo],
  template: "<app-demo></app-demo>", 
  
})
export class AppComponent {
	title = 'app-demo';

	wcfSubcompsSubscription: Subscription;

	constructor(private wcfSubcompsService: WcfSubcomps) {
		this.wcfSubcompsSubscription = Subscription.EMPTY;
	}
	
	ngAfterViewInit () {
		this.wcfSubcompsService.changeAttribute({"id":"bloque-pestanas", "consultas":"off"});
		this.wcfSubcompsService.changeAttribute({"id":"bloque-pestanas.enlace-volver", "texto_enlace":"Nuevo texto del enlace"});
	}

}

Error de javascript en desarrollo

En modo desarrollo, es decir cuando se ejecuta una aplicación Angular con ng serve desde la linea de comandos, el motor de ejecución agrega un control adicional sobre los cambios en las expresiones incluidas en los templates. Este control es solo informativo y no se realiza en producción, es decir cuando la aplicación se incorpora luego de compilarla con ng build.

Los mensajes de error tienen el formato que se muestra a continuación, y pueden ser ignorados:

Mensaje de error en desarrollo
Con Angular en modo desarrollo, se avisa con un error de que cambiaron los valores de los inputs incluidos en el template de un componente. Esto es solo informativo y no ocurre en producción.

Puede obtener información adicional en la página de la documentación de Angular sobre el error.

  1. El servicio inyectable, de acuerdo con las recomendaciones de Angular, implementa un Observer Pattern ↩︎
  2. El código que ya existe se muestra más claro que el que hay que añadir ↩︎

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

7 + 8 =