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.
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.
@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.
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.
*ngComponentOutlet
Nous commençons par remplacer cette propriété de lecteur par un @Input
. Et c'est simplement tapé dans notre interface de lecteur.
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.
@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.
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.