paint-brush
Comment utiliser Angular @Input pour transmettre des données à des composants créés dynamiquementby@briantreese
323
323

Comment utiliser Angular @Input pour transmettre des données à des composants créés dynamiquement

Brian Treese4m2024/02/27
Read on Terminal Reader

Angular 16 vous permet de transmettre des données entre des composants créés dynamiquement du parent à l'enfant. Auparavant, nous devions fournir les informations dans le composant parent puis les injecter dans le composant enfant. Maintenant, nous pouvons le faire en utilisant le décorateur `@Input` à la place.
featured image - Comment utiliser Angular @Input pour transmettre des données à des composants créés dynamiquement
Brian Treese HackerNoon profile picture

Si vous utilisez des composants créés dynamiquement dans Angular, vous avez probablement eu du mal à transmettre des informations entre les composants parent et enfant en cas de besoin. Vous devez fournir les informations dans le parent, puis les injecter dans le composant enfant. Bien que ce ne soit pas nécessairement difficile à faire, cela entraîne beaucoup de code passe-partout supplémentaire.


Ce serait tellement mieux si nous pouvions simplement utiliser le décorateur @Input comme nous en avons l'habitude. Bien devinez quoi? Angular prend en charge exactement cette chose à partir de la version seize. Dans cet article, je vais vous montrer comment. Très bien, allons-y.

Transmission de données à l'ancienne à l'aide de l'injecteur angulaire

Tout d’abord, regardons comment nous transmettions les données aux composants créés dynamiquement à partir du parent. Ici, dans cet exemple, dans le modèle de composant, nous avons notre *ngComponentOutlet et nous le transmettons à notre composant lecteur.


Dans ce cas, nous transmettons également un injecteur enfant personnalisé, et c'est ainsi que nous injections auparavant les données du composant enfant.

main.ts

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


Et pour créer cet injecteur enfant, nous devions créer une propriété afin qu'elle puisse être définie puis utilisée dans le modèle.


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


Ensuite, nous avons dû injecter l'injecteur à partir du noyau angulaire du constructeur.


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


Après cela, nous devions configurer l'injecteur enfant à l'aide de la méthode create et du tableau des fournisseurs pour fournir notre jeton de joueur à l'enfant.


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


Et enfin, dans le composant enfant, notre composant player, nous devions définir notre propriété player avec la méthode inject du noyau angulaire.

lecteur.component.ts

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


Donc, tout cela consiste simplement à passer un simple objet joueur à un composant dynamique. Je veux dire, si ce n'était pas un composant dynamique, nous en ferions simplement un @Input et lierions simplement l'objet de données du lecteur au @Input du parent. Mais il s’agit d’un composant créé dynamiquement, nous ne pouvons donc pas faire cela, n’est-ce pas ?


Eh bien, depuis Angular seize, nous pouvons utiliser des @Input à la place, et c'est beaucoup plus simple que ce que nous avons vu jusqu'à présent.

Transmission de données d'une nouvelle manière à l'aide de l'objet d'entrées *ngComponentOutlet

Nous commençons par remplacer cette propriété de lecteur par un @Input . Et c'est simplement tapé dans notre interface de lecteur.

lecteur.component.ts

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


Désormais, nous pouvons supprimer la méthode d'injection et les importations de jetons de joueur puisqu'elles ne sont plus nécessaires. Ensuite, de retour dans notre parent, dans le modèle, nous pouvons supprimer l'injecteur et le remplacer par un objet d'entrées. Nous pouvons transmettre cet objet sur n'importe quel nombre d'entrées. Ainsi, si nous avions cinq entrées, nous inclurions simplement leurs noms, puis transmettrions à chacune les données dont nous avons besoin.


Mais dans ce cas, nous n'avons qu'une seule entrée sur notre composant enfant, player, c'est donc tout ce dont nous avons besoin pour le transmettre.

main.ts

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


Maintenant, nous pouvons retirer l'injecteur enfant. Cela signifie que nous pouvons également supprimer complètement le constructeur. Et enfin, nous pouvons supprimer l'injecteur du noyau angulaire et l'importation du jeton du joueur puisque nous ne les utilisons plus.


 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; }


Et c'est tout. Nous pouvons voir que tout fonctionne comme avant. Donc, c'est un peu plus facile à réaliser et moins de code aussi, ce qui est toujours génial.


Ce qui est décevant, c'est que même si les @Input sont pris en charge, les @Output ne le sont pas. Un peu décevant, mais c'est comme ça. Espérons qu'ils ajouteront un support à l'avenir, car cela serait également très pratique, mais nous devrons simplement attendre et voir.

Vous voulez le voir en action ?

Découvrez le code de démonstration et des exemples de ces techniques dans l'exemple Stackblitz ci-dessous. Si vous avez des questions ou des idées, n'hésitez pas à laisser un commentaire.