Различные способы передачи данных в компоненты Angular

от автора

Привет, Хабр! Представляю вашему вниманию перевод статьи «Different Ways to Pass Inputs to a Component in Angular» автора Netanel Basal.

image

В этой статье, мы разберём три разных способа передачи данных в компонент. В следующем примере мы будем использовать select как главный компонент, но методы, используемые в нём релевантны и в других компонентах.

Создадим компонент select, который получает следующие входные данные — size и placement.

Использование Inputs

Первый метод, с которым мы все знакомы — использование декорантора Input.

@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' } 

И этот код отлично работает, за исключением того, что он не такой гибкий. Например нам нужно задать переменной size значение large для любого select в нашем приложении. Таким образом мы должны разрешить клиетну переписать любой input на глобальном уровне.

Использование зависимости Injection

Для этого мы можем использовать функцию внедрения зависимостей 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   } } 

Для начала нам нужно создать конфигурацию провайдера. Этот провайдер может быть использован как token, type, а также задавать значения по умолчанию для каждого input. Используем это в нашем компоненте select:

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

Теперь мы можем переписать выбранные inputs на уровне нашего приложения:

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

Но это не всё. Так же мы можем использовать это для передачи различных inputs на уровне компонентов. Например у нас есть компонент, который мы используем несколько раз в приложении. В каждом случае нам нужно использовать величину small:

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

Мы можем добавить это в компонет providers и эта величина будет использована для всех компонентов, объявленных и дочерних в шаблонах. Но мы всё ещё можем переписать эту переменную, напрямую следующим образом:

@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 {} 

Такую же стратегию применяют для lazy modules потому что она создают новую инъекцию.

Использование Directives

Предположим у нас есть компоненты с множеством входных данных. Мы устанавливаем одинаковые значения для большинства из них. В примере это будет выглядеть так:

<!-- 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> 

Мы можем повторять эти значения, но можем создать директиву, которая передаст необходимые значения всех переменных:

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

И мы можем использовать эту директиву где нам нужно:

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

ссылка на оригинал статьи https://habr.com/ru/post/502762/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *