angular
February 20
Host-директивы в Angular
Начиная с Angular 15 появилась новая возможность: хост-директивы.
@Component({ selector: '...', host: { ... '[class.my-disabled-class]': 'disabled', '[attr.disabled]': 'disabled || null', '[attr.aria-disabled]': 'disabled || null', ... }, template: `...` }) class MyComponent { @Input() public disabled = false; // many other stuffs }
Как можно улучшить этот код? Первая мысль - создать директиву.
@Directive({ selector: '[myDisabledState]', standalone: true, host: { '[attr.disabled]': 'disabled || null', '[attr.aria-disabled]': 'disabled || null', '[class.rc-disabled]': 'disabled', }, }) export class DisabledStateDirective { @Input() public disabled = false; }
И теперь код можно упростить до такого:
@Component({ selector: '...', host: { ... }, hostDirectives: [{ directive: DisabledStateDirective, inputs: ['disabled'], }], template: `...` }) class MyComponent { // many other stuffs }
В таком случае код читается проще, и соблюдается принцип разделения ответственности. Но есть сложность, с выносом логики в директиву теряется доступ к свойству disabled. Разработчики Angular предусмотрели подобное поведение:
@Component({ selector: '...', host: { ... }, hostDirectives: [{ directive: DisabledStateDirective, inputs: ['disabled'], }], template: `...` }) class MyComponent { private readonly _disabledState: DisabledStateDirective = inject(DisabledStateDirective, { self: true }); public myFunction(): void { if (this.disabledState.disabled) { } } }
Мы просто можем использовать метод inject
, чтобы получить DisabledStateDirective.