Angular 结构指令:用另一个组件包装宿主元素
Posted
技术标签:
【中文标题】Angular 结构指令:用另一个组件包装宿主元素【英文标题】:Angular structural directive: wrap the host element with some another component 【发布时间】:2018-05-01 21:46:55 【问题描述】:我有最简单的 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>
我希望指令为我做这件事。我知道我可以使用组件范例并创建HelloComponent
而不是HelloDirective
并使用ng-template
等与template
或templateUrl
属性在@Component
装饰器上定义的模板... 但是有吗一种可以与指令范式一起使用的方法来实现这样的结果?
【问题讨论】:
是否要将指令的内容嵌入到组件中? @yurzui 是的,然后将结果传递给初始模板而不是指令的内容。这样它就可以在末尾被解释为<div *hello><my-component>Hello Directive</my-component></div>
(而不是<div *hello>Hello Directive</div>
)。
my-component
是否包含ng-content
?
@yurzui 它可以完全定制以提供正确的行为。此任务中的my-component
实现没有限制。
【参考方案1】:
您可以动态创建组件并将可投影节点传递给它。所以它可能看起来像
@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();
您必须将MyComponent
添加到@NgModule
的entryComponents
数组中
完整示例可在 Stackblitz
上找到另见
Creating a angular2 component with ng-content dynamically【讨论】:
如果我在 hello 指令中使用嵌套组件,它就不起作用。你有解决这个问题的建议吗:stackblitz.com/edit/angular-97ckey?embed=1&file=app/… @MuratÇorlu 你的意思是 hello 组件没有得到输入吗?那是因为它的视图不是角度变化检测树的一部分。试试这个stackblitz.com/edit/angular-jrtnmn?file=app/app.component.ts 太好了,谢谢。另一个问题是,现在 hello 指令中的 hello 组件在指令嵌入内容时正在初始化,但在删除内容时不会销毁:stackblitz.com/edit/… 你是否也有建议在我们从 dom 中删除内容时销毁 hello 组件? @yurzui 我有一个来自 devextreme 的 dx-text-box,并且代码无法正常工作,在我解决了这个问题后我更新了你的答案(因为许多开发人员复制粘贴并且他们希望它能够解决的盒子)以上是关于Angular 结构指令:用另一个组件包装宿主元素的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 结构指令中使用动态组件会产生额外的 HTML 标记。如何删除或更换它?