paint-brush
Como usar Angular @Input para passar dados para componentes criados dinamicamenteby@briantreese
323
323

Como usar Angular @Input para passar dados para componentes criados dinamicamente

Brian Treese4m2024/02/27
Read on Terminal Reader

Angular 16 permite passar dados entre componentes criados dinamicamente do pai para o filho. Anteriormente, tínhamos que fornecer as informações no componente pai e depois injetá-las no componente filho. Agora, podemos fazer isso usando o decorador `@Input`.
featured image - Como usar Angular @Input para passar dados para componentes criados dinamicamente
Brian Treese HackerNoon profile picture

Se você estiver usando componentes criados dinamicamente no Angular, provavelmente terá dificuldade em passar informações entre os componentes pai e filho quando necessário. Você precisa fornecer as informações no pai e, em seguida, injetá-las no componente filho. Embora não seja necessariamente difícil de fazer, resulta em muito código clichê extra.


Seria muito melhor se pudéssemos usar o decorador @Input como estamos acostumados. Bem, adivinhe? Angular suporta fazer exatamente isso a partir da versão dezesseis. Neste post vou te mostrar como. Tudo bem, vamos lá.

Passando dados da maneira antiga usando o injetor angular

Primeiro, vamos ver como costumávamos passar dados para componentes criados dinamicamente a partir do pai. Aqui, neste exemplo, dentro do modelo de componente, temos nosso *ngComponentOutlet e o estamos passando para nosso componente player.


Nesse caso, também estamos passando um injetor filho personalizado e é assim que injetaríamos os dados do componente filho antes.

principal.ts

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


E para criar esse injetor filho, precisávamos criar uma propriedade para que pudesse ser configurada e usada dentro do template.


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


Então, precisávamos injetar o Injector do núcleo angular dentro do construtor.


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


Depois disso, precisávamos definir o injetor filho usando o método create e o array de provedores para fornecer nosso token de jogador ao filho.


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


E finalmente, no componente filho, nosso componente player, precisávamos definir nossa propriedade player com o método inject do núcleo angular.

player.component.ts

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


Então, tudo isso é apenas para passar um objeto de jogador simples para um componente dinâmico. Quero dizer, se este não fosse um componente dinâmico, simplesmente tornaríamos isso um @Input e vincularíamos o objeto de dados do jogador ao @Input no pai. Mas este é um componente criado dinamicamente, então não podemos fazer isso, certo?


Bem, a partir do Angular dezesseis, podemos usar @Input s, e é muito mais simples do que vimos até agora.

Passando dados de uma nova maneira usando o objeto *ngComponentOutlet Inputs

Começamos alterando esta propriedade do player para @Input . E é simplesmente digitado na interface do player.

player.component.ts

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


Agora, podemos remover o método inject e as importações de tokens de jogadores, pois eles não são mais necessários. Então, de volta ao nosso pai, no modelo, podemos remover o injetor e, em vez disso, substituí-lo por um objeto de entrada. Podemos passar este objeto em qualquer número de entradas. Então, se tivéssemos cinco entradas, apenas incluiríamos seus nomes e passaríamos a cada uma os dados necessários.


Mas neste caso, temos apenas uma entrada em nosso componente filho, player, então isso é tudo que precisamos para passá-lo.

principal.ts

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


Agora podemos remover o injetor infantil. Isso significa que também podemos remover completamente o construtor. E finalmente, podemos remover o Injector do núcleo angular e a importação do token do jogador, já que não os estamos mais usando.


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


E é isso. Podemos ver que tudo funciona como antes. Então, é um pouco mais fácil de executar e menos código também, o que é sempre ótimo.


Uma chatice é que, embora @Input s sejam suportados, @Output s não são. Meio chato, mas é o que é. Esperançosamente, eles adicionarão suporte no futuro porque isso também seria muito útil, mas teremos que esperar para ver.

Quer ver isso em ação?

Confira o código de demonstração e exemplos dessas técnicas no exemplo Stackblitz abaixo. Se você tiver alguma dúvida ou opinião, não hesite em deixar um comentário.