问题
I have simplest Angular structural directive:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[hello]' })
export class HelloDirective {
constructor(
private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
I use it this way:
<div *hello>Hello Directive</div>
It shows me "Hello Directive" message as expected. Now I want to change the content by wrapping it with some another component:
<my-component>Hello Directive</my-component>
And I want the directive to do it for me. I know that I can use a Component paradigm and create HelloComponent
instead of HelloDirective
and use ng-template
etc with the template defined by template
or templateUrl
property on the @Component
decorator... But is there an approach that could be used with a Directive paradigm to achieve such a result?
回答1:
You can create component dynamically and pass projectable nodes to it. So it could look like
@Directive({ selector: '[hello]' })
export class HelloDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private resolver: ComponentFactoryResolver) {
}
ngOnInit() {
const templateView = this.templateRef.createEmbeddedView({});
const compFactory = this.resolver.resolveComponentFactory(MyComponent);
this.viewContainer.createComponent(
compFactory, null, this.viewContainer.injector, [templateView.rootNodes])
}
}
You have to add MyComponent
to entryComponents
array of your @NgModule
Complete example can be found on Stackblitz
See also
- Creating a angular2 component with ng-content dynamically
来源:https://stackoverflow.com/questions/47362119/angular-structural-directive-wrap-the-host-element-with-some-another-component