我有最简单的Angular结构指令:
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); } }
我用这种方式:
<div *hello>Hello Directive</div>
它按预期显示“Hello Directive”消息.现在我想通过用另一个组件包装来更改内容:
<my-component>Hello Directive</my-component>
我希望该指令能够为我做到这一点.我知道我可以使用Component范例并创建HelloComponent而不是HelloDirective,并使用ng-template等与@Component装饰器上的template或templateUrl属性定义的模板…但是有没有一种方法可以用于指令范式达到这样的结果?
解决方法
您可以动态创建组件并将可投影节点传递给它.所以它看起来像
@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]) } }
您必须将MyComponent添加到@NgModule的entryComponents数组中
完整的示例可以在Stackblitz找到
也可以看看