angular
February 20, 2024
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.