问题描述
我有最简单的 Angular 结构指令:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';@Directive({ 选择器: '[你好]' })导出类 HelloDirective {构造函数(私有 templateRef: TemplateRef, private viewContainer: ViewContainerRef) {this.viewContainer.createEmbeddedView(this.templateRef);}}
我是这样使用的:
Hello 指令
它按预期向我显示Hello Directive"消息.现在我想通过用其他组件包装它来更改内容:
我希望指令为我做这件事.我知道我可以使用组件范例并创建 HelloComponent
而不是 HelloDirective
并使用 ng-template
等与 定义的模板
或 @Component
装饰器上的 templatetemplateUrl
属性......但是有没有一种方法可以与指令范例一起使用来实现这样的结果?
您可以动态创建组件并将可投影节点传递给它.所以它看起来像
@Directive({ 选择器: '[hello]' })导出类 HelloDirective 实现 OnInit、DoCheck {模板视图:EmbeddedViewRef;构造函数(私有模板引用:模板引用,私有视图容器:ViewContainerRef,私有解析器:ComponentFactoryResolver) {}ngOnInit() {this.templateView = this.templateRef.createEmbeddedView({});const compFactory = this.resolver.resolveComponentFactory(MyComponent);this.viewContainer.createComponent(compFactory, null, this.viewContainer.injector, [this.templateView.rootNodes])}ngDoCheck(): 无效 {如果(this.templateView){this.templateView.detectChanges();}}}
您必须将 MyComponent
添加到 @NgModule
entryComponents
数组完整示例可在 Stackblitz
另见
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?
You can create component dynamically and pass projectable nodes to it. So it could look like
@Directive({ selector: '[hello]' })
export class HelloDirective implements OnInit, DoCheck {
templateView: EmbeddedViewRef<any>;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private resolver: ComponentFactoryResolver) {
}
ngOnInit() {
this.templateView = this.templateRef.createEmbeddedView({});
const compFactory = this.resolver.resolveComponentFactory(MyComponent);
this.viewContainer.createComponent(
compFactory, null, this.viewContainer.injector, [this.templateView.rootNodes])
}
ngDoCheck(): void {
if (this.templateView) {
this.templateView.detectChanges();
}
}
}
You have to add MyComponent
to entryComponents
array of your @NgModule
Complete example can be found on Stackblitz
See also
这篇关于Angular 结构指令:用其他组件包裹宿主元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!