Структурные и атрибутивные директивы в Angular
Любой, кто работал с Angular, использовал бы директивы. По словам официальногоУгловая документациясуществует 3 типа директив:
- Составные части
- Структурные директивы, такие как
ngIf
а такжеngFor
- Директивы атрибутов, такие как
ngStyle
Этот пост в первую очередь документирует создание и использование пользовательских структурных директив и то, как они отличаются от более часто используемых директив атрибутов.
Что такое структурные директивы?
Как следует из названия, структурные директивы отвечают за управление структурой DOM путем добавления, удаления или изменения элементов, к которым они присоединены. Возможно, самая распространенная структурная директива, которую большинство разработчиков Angular используют ngIf
директива, которая используется для отображения/скрытия элементов на основе логического условия.
Совет начинающим: структурные директивы имеют префикс
*
в то время как директивы атрибутов можно использовать, просто добавив их селектор в качестве атрибута к элементу.
Создание собственной структурной директивы.
Предположим, у вас есть конфигурация оплаты, на основе которой вы хотите показывать или скрывать определенные элементы для определенных пользователей. Мы создадим директиву, которая будет принимать входные данные для флага функции, а затем показывать или скрывать элемент в зависимости от конфигурации платежа.
Создание структурной директивы очень похоже на создание директивы атрибута.
@Directive({ selector: '[appRenderIfEnabled]'})
export class RenderFeatureDirective implements OnInit{ private flag: string; @Input() set appRenderIfEnabled(flag: string){ this.flag = flag; } constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef, private configService: ConfigService ) {} ngOnInit(){ this.configService.isEnabled(this.flag).subscribe(enabled=>{ if(enabled){ this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } }); }
}
Как видите, директива принимает один вход, имя которого в данном случае должно совпадать с выбранным вами селектором (appRenderIfEnabled). Директива получает ссылку на TemplateRef
и ViewContainer
это потому, что директива создает встроенное представление внутри заданного ViewContainer
и TemplateRef
используется для доступа к содержимому шаблона/элемента, к которому прикреплена директива.
Теперь пользовательская директива готова к использованию, добавьте ее к любому компоненту, например:
<my-pro-version-component *appRenderIfEnabled="'PRO_PACKAGE_ONLY'"></my-pro-version-component>
Использование дополнительного @Input с вашей директивой.
До сих пор наша директива просто принимала флаг в качестве входных данных, но что, если вы хотите предоставить значение по умолчанию в случае отсутствия конфигурации?
Ключевой частью наличия дополнительных входных данных в структурных директивах является то, что имя входного свойства должно начинаться с селектора. В нашем случае мы хотим defaultConfig
поэтому имя входного свойства будет appRenderIfEnabledDefaultConfig
.
@Directive({ selector: '[appRenderIfEnabled]'})
export class RenderFeatureDirective implements OnInit{ private flag: string; private defaultConfig = false; @Input() set appRenderIfEnabled(flag: string){ this.flag = flag; } @Input() set appRenderIfEnabledDefaultConfig(conf:boolean){ this.defaultConfig = conf; }
Новый ввод можно просто добавить, используя следующий синтаксис:
<my-pro-version-component *appRenderIfEnabled="'PRO_PACKAGE_ONLY';defaultConfig: true"></my-pro-version-component>
Первоначально опубликовано в моем блоге — Неопределенный