
В этой статье, мы разберём три разных способа передачи данных в компонент. В следующем примере мы будем использовать 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/
Добавить комментарий