paint-brush
Cómo utilizar Angular @Input para pasar datos a componentes creados dinámicamenteby@briantreese
319
319

Cómo utilizar Angular @Input para pasar datos a componentes creados dinámicamente

Brian Treese4m2024/02/27
Read on Terminal Reader

Angular 16 le permite pasar datos entre componentes creados dinámicamente del padre al hijo. Anteriormente, teníamos que proporcionar la información en el componente principal y luego inyectarla en el componente secundario. Ahora, podemos hacer esto usando el decorador `@Input`.
featured image - Cómo utilizar Angular @Input para pasar datos a componentes creados dinámicamente
Brian Treese HackerNoon profile picture

Si está utilizando componentes creados dinámicamente en Angular, probablemente le haya resultado difícil pasar información entre los componentes principal y secundario cuando sea necesario. Debe proporcionar la información en el componente principal y luego inyectarla dentro del componente secundario. Si bien no es necesariamente difícil de hacer, genera una gran cantidad de código repetitivo adicional.


Sería mucho mejor si pudiéramos usar el decorador @Input como estamos acostumbrados. ¿Bien adivina que? Angular admite hacer exactamente esto a partir de la versión dieciséis. En esta publicación, te mostraré cómo. Muy bien, vayamos a ello.

Pasar datos a la antigua usanza utilizando el inyector angular

Primero, veamos cómo solíamos pasar datos a componentes creados dinámicamente desde el padre. Aquí, en este ejemplo, dentro de la plantilla del componente, tenemos nuestro *ngComponentOutlet y lo pasamos a nuestro componente reproductor.


En este caso, también estamos pasando un inyector secundario personalizado, y así es como inyectaríamos los datos para el componente secundario antes.

principal.ts

 @Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; injector: childInjector"></ng-container> ` }) export class App { protected playerComponent = PlayerComponent; }


Y para crear este inyector secundario, necesitábamos crear una propiedad para poder configurarlo y luego usarlo dentro de la plantilla.


 export class App { protected childInjector?: Injector; ... }


Luego, necesitábamos inyectar el Inyector desde el núcleo angular dentro del constructor.


 export class App { ... constructor(private injector: Injector) { } }


Después de eso, necesitábamos configurar el inyector secundario usando el método de creación y la matriz de proveedores para proporcionar nuestro token de jugador al niño.


 export class App { ... constructor(private injector: Injector) { this.childInjector = Injector.create({ providers: [ { provide: PlayerToken, useValue: this.player } ], parent: this.injector }); } }


Y finalmente, en el componente secundario, nuestro componente reproductor, necesitábamos establecer nuestra propiedad del reproductor con el método de inyección del núcleo angular.

reproductor.componente.ts

 export class PlayerComponent { protected player?: Player = inject(PlayerToken); }


Entonces, todo esto es solo para pasar un objeto reproductor simple a un componente dinámico. Quiero decir, si este no fuera un componente dinámico, simplemente lo convertiríamos en un @Input y simplemente vincularíamos el objeto de datos del reproductor al @Input en el padre. Pero este es un componente creado dinámicamente, por lo que no podemos hacer esto, ¿verdad?


Bueno, a partir de Angular dieciséis, podemos usar @Input en su lugar, y es mucho más simple de lo que hemos visto hasta ahora.

Pasar datos de una nueva manera utilizando el objeto de entradas *ngComponentOutlet

Comenzamos cambiando esta propiedad del reproductor a @Input . Y simplemente se escribe en la interfaz de nuestro reproductor.

reproductor.componente.ts

 export class PlayerComponent { @Input() player?: Player; }


Ahora podemos eliminar el método de inyección y las importaciones de tokens de jugador, ya que ya no son necesarios. Luego, volviendo a nuestro padre, en la plantilla, podemos quitar el inyector y, en su lugar, reemplazarlo con un objeto de entradas. Podemos pasar este objeto en cualquier número de entradas. Entonces, si tuviéramos cinco entradas, simplemente incluiríamos sus nombres y luego pasaríamos a cada una los datos que necesitemos.


Pero en este caso, solo tenemos una entrada en nuestro componente secundario, player, así que eso es todo lo que necesitamos para pasarlo.

principal.ts

 @Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; inputs: { player }"></ng-container> ` })


Ahora podemos quitar el inyector infantil. Esto significa que también podemos eliminar el constructor por completo. Y finalmente, podemos eliminar el Inyector del núcleo angular y la importación del token del jugador, ya que ya no los usaremos.


 export class App { protected player: Player = { name: 'LeBron James', games: 1421, points: 38652, fieldGoalPercentage: 0.505, threePointPercentage: 0.345, imageName: 'lebron-james' }; protected playerComponent = PlayerComponent; }


Y eso es. Podemos ver que todo funciona como antes. Por lo tanto, es un poco más fácil de lograr y también menos código, lo cual siempre es genial.


Sin embargo, lo malo es que, si bien los @Input son compatibles, los @Output no lo son. Una especie de fastidio, pero es lo que hay. Con suerte, agregarán soporte en el futuro porque esto también sería muy útil, pero tendremos que esperar y ver.

¿Quieres verlo en acción?

Consulte el código de demostración y los ejemplos de estas técnicas en el ejemplo de Stackblitz a continuación. Si tienes alguna pregunta o idea, no dudes en dejar un comentario.