Maneiras diferentes de passar dados para componentes angulares

Olá Habr! Apresento a você a tradução do artigo “Diferentes maneiras de passar entradas para um componente em angular” de Netanel Basal.

imagem

Neste artigo, analisaremos três maneiras diferentes de transferir dados para um componente. No exemplo a seguir, usaremos select como o componente principal, mas os métodos usados ​​nele são relevantes em outros componentes.

Crie um componente selecionado que receba as seguintes entradas - tamanho e posicionamento .

Usando entradas


O primeiro método com o qual estamos familiarizados é usar o decorador de entrada .

@Component({
  selector: 'app-select',
  template: `
    <p><b>Size</b> {{ size }}</p>
    <p><b>Placement:</b> {{ placement }}</p>    
    `
})
export class SelectComponent {
  @Input() size: 'sm' | 'md' | 'lg' = 'md';
  @Input() placement: 'top' | 'bottom' | 'right' | 'left'  = 'bottom'
}

E esse código funciona muito bem, exceto que não é tão flexível. Por exemplo, precisamos definir a variável de tamanho como grande para qualquer seleção em nosso aplicativo. Portanto, devemos permitir que o cliente reescreva qualquer entrada globalmente.

Usando Dependência de Injeção


Para fazer isso, podemos usar a função de injeção de dependência angular.

import { InjectionToken, Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class SelectConfig {
  size: 'sm' | 'md' | 'lg' = 'md'
  placement: 'top' | 'bottom' | 'right' | 'left' = 'bottom';
}

export function setSelectConfig(config: Partial<SelectConfig>) {
  return {
    ...new SelectConfig(),
    ...config
  }
}

Primeiro, precisamos criar uma configuração de provedor. Esse provedor pode ser usado como token , tipo e também definir valores padrão para cada entrada . Usamos isso em nosso componente selecionado :

@Component({
  selector: 'app-select',
  template: `
    <p><b>Size</b> {{ size }}</p>
    <p><b>Placement:</b> {{ placement }}</p>    
    `
})
export class SelectComponent {
  @Input() size: SelectConfig['size'];
  @Input() placement: SelectConfig['placement'];

  constructor(private config: SelectConfig) {
    this.size = config.size;
    this.placement = config.placement;
  }
}

Agora podemos reescrever as entradas selecionadas no nível do nosso aplicativo:

@NgModule({
  providers: [
    {
      provide: SelectConfig,
      useValue: setSelectConfig({
        size: 'lg'
      })
    }
  ]
  bootstrap: [AppComponent]
})
export class AppModule { }

Mas isso não é tudo. Também podemos usar isso para transmitir várias entradas no nível do componente. Por exemplo, temos um componente que usamos várias vezes no aplicativo. Em cada caso, precisamos usar o pequeno valor :

@Component({
  selector: 'app-todos-page',
  template: `<app-select></app-select>`,
  providers: [
    {
      provide: SelectConfig,
      useValue: setSelectConfig({
        size: 'sm'
      })
    }
  ]
})
export class TodosPageComponent {}

Podemos adicionar isso ao componente de fornecedores e esse valor será usado para todos os componentes declarados e filhos nos modelos. Mas ainda podemos reescrever essa variável diretamente da seguinte maneira:

@Component({
  selector: 'app-todos-page',
  template: `
   <app-select></app-select>
   <app-select size="lg"></app-select>
`,
  providers: [
    {
      provide: SelectConfig,
      useValue: setSelectConfig({
        size: 'sm'
      })
    }
  ]
})
export class TodosPageComponent {}

A mesma estratégia é usada para módulos preguiçosos porque cria uma nova injeção.

Usando diretivas


Suponha que tenhamos componentes com muita entrada. Definimos os mesmos valores para a maioria deles. No exemplo, ficará assim:

<!-- It can be in the same template or in different places in the app -->
<app-select size="lg" position="right" inputThree="someValue"></app-select>
<app-select size="lg" position="right" inputThree="someValue"></app-select>
<app-select size="lg" position="right  inputThree="someValue"></app-select>
<app-select size="lg" position="right" inputThree="someValue"></app-select>
<app-select size="lg" position="right" inputThree="someValue"></app-select>

Podemos repetir esses valores, mas podemos criar uma diretiva que passará os valores necessários de todas as variáveis:

@Directive({
  selector: '[selectConfigOne]',
  providers: [{
    provide: SelectConfig,
    useValue: setSelectConfig({
      size: 'lg',
      placement: 'right',
      inputThree: 'someValue'
    })
  }]
})
export class SelectConfigOneDirective {}

E podemos usar esta diretiva onde precisamos:

<h1>Using Inputs</h1>
<app-select size="lg"></app-select>
<app-select placement="top"></app-select>

<h1>Using a Directive</h1>
<app-select selectConfigOne></app-select>

<app-todos-page></app-todos-page>

All Articles