Построение директивы обертки (обернуть некоторый контент / компонент) в angular2
Я довольно новые строительные директивы с Angular2. Я хочу создать всплывающую директиву, которая обернет содержимое некоторыми классами CSS.
содержание
Контент может быть простым текстом и заголовками, такими как:
<div class="data">
<h2>Header</h2>
Content to be placed here.
</div>
Затем я хочу дать этому атрибуту директивы, например: popup
<div class="data" popup>
<h2>Header</h2>
Content to be placed here.
</div>
Что директива должна сделать, это обернуть div внутри, скажем:
<div class="some class">
<div class="some other class">
<div class="data">
<h2>Header</h2>
Content to be placed here.
</div>
</div>
</div>
Случай, который я описал, это атрибут или структурные директивы.
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: `[popup]`
})
export class PopupDirective {
}
2 ответа
Другой ответ связан, но отличается.
Для более подробного ознакомления посмотрите следующее: Как условно обернуть div вокруг ng-content - мое решение для Angular 4, но у связанного вопроса есть некоторые подсказки о том, как это можно сделать для Angular 2.
Я решил эту проблему вместе с компонентом и директивой. Мой компонент выглядит примерно так:
import { Component, Input, TemplateRef } from '@angular/core';
@Component({
selector: 'my-wrapper-container',
template: `
<div class="whatever">
<ng-container *ngTemplateOutlet="template"></ng-container>
</div>
`
})
export class WrapperContainerComponent {
@Input() template: TemplateRef<any>;
}
и моя директива такова:
import { Directive, OnInit, Input, TemplateRef, ComponentRef, ComponentFactoryResolver, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[myWrapperDirective]'
})
export class WrapperDirective implements OnInit {
private wrapperContainer: ComponentRef<WrapperContainerComponent>;
constructor(
private templateRef: TemplateRef<any>,
private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver
) { }
ngOnInit() {
const containerFactory = this.componentFactoryResolver.resolveComponentFactory(WrapperContainerComponent);
this.wrapperContainer = this.viewContainerRef.createComponent(containerFactory);
this.wrapperContainer.instance.template = this.templateRef;
}
}
Чтобы иметь возможность загружать ваш компонент динамически, вы должны перечислить его как entryComponent
внутри вашего модуля:
@NgModule({
imports: [CommonModule],
declarations: [WrapperContainerComponent, WrapperDirective],
exports: [WrapperContainerComponent, WrapperDirective],
entryComponents: [WrapperContainerComponent]
})
export class MyModule{}
поэтому HTML в конце концов:
<some_tag *myWrapperDirective />
Который отображается как:
<my-wrapper-container>
<div class="whatever">
<some_tag />
</div>
</my-wrapper-container>
Вы можете добиться этого с помощью селектора атрибутов компонента и Angular 2 Content Projection. <ng-content>
@Component({
selector: 'my-app',
template: `
<div class="app">
<div class="data" myWrapper>
<h2>Header</h2>
Content to be placed here.
</div>
</div>
`
})
export class AppComponent {}
@Component({
selector: '[myWrapper]',
template: `
<div class="my-class">
<div class="my-sub-class">
<ng-content></ng-content>
</div>
</div>
`
})
export class MyComponent {
}