结构指令可以使用@ContentChild 来引用子组件吗? [英] Can a structural directive refer to a child component using @ContentChild?

查看:19
本文介绍了结构指令可以使用@ContentChild 来引用子组件吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个自定义指令 ParentDirective 和自定义组件 ChildComponent 排列如下:

<app-child></app-child>

...然后我可以在指令中使用 @ContentChild 来引用组件:

@ContentChild(ChildComponent) child: ChildComponent;

请参阅此 StackBlitz 的工作原理.(它登录到控制台以显示 child 成员已设置).

但是,如果我将 appParent 更改为 structural 指令,则永远不会设置 child 成员.

<app-child></app-child>

请参阅此 StackBlitz.

是否不能将 @ContentChild 与结构指令一起使用?

解决方案

我认为你不能,这是由于 angular 对这两种类型的指令使用的设计.通过 TemplateRef 创建指令并通过 ViewContainerRefcreateEmbeddedView 注入它 将模板生成为 dom 中的同级,而不是子级.因此,Angular 的注入也尊重了这一点,所以孩子和创建的地方不能看到对方.你可以把它画在你的脑海里,作为一个额外的附加层.

这里createEmbeddedView

的源代码

 createEmbeddedView(context: any): EmbeddedViewRef{返回新的 ViewRef_(Services.createEmbeddedView(this._parentView, this._def, this._def.element !.template !, context));}

如您所见,它返回一个新的 ViewRef,在其中注入您的 context.

更多详情请点击此处.

If I have a custom directive ParentDirective and custom component ChildComponent arranged like so:

<div appParent>
  <app-child></app-child>
</div>

...then I can use @ContentChild in the directive to refer to the component:

@ContentChild(ChildComponent) child: ChildComponent;

See this StackBlitz where this is working. (It logs to the console to show that the child member is set).

However, if I change appParent into a structural directive, then the child member is never set.

<div *appParent>
  <app-child></app-child>
</div>

See this StackBlitz.

Is it not possible to use @ContentChild with structural directives?

解决方案

I think you cannot, and that is due to the design used by angular for both type of directives. Creating a directive via TemplateRef and injecting it via createEmbeddedView of ViewContainerRef generates the template as a sibling in the dom, not as a child. Therefore, Angular's injection also respects this so the child and the place of creation cannot see each other. You can draw it in your mind as an extra added layer there.

Here is the source code of the createEmbeddedView

  createEmbeddedView(context: any): EmbeddedViewRef<any> {
    return new ViewRef_(Services.createEmbeddedView(
        this._parentView, this._def, this._def.element !.template !, context));
  }

As you can see, it returns a new ViewRef where it injects your context.

More details here.

这篇关于结构指令可以使用@ContentChild 来引用子组件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆