Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a structural directive refer to a child component using @ContentChild?

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?

like image 446
Gary McGill Avatar asked Nov 30 '18 15:11

Gary McGill


People also ask

When should I use ContentChild?

ViewChild is used to select an element from component's template while ContentChild is used to select projected content.

What is the use of ContentChild in Angular?

Descriptionlink. Use to get the first element or the directive matching the selector from the content DOM. If the content DOM changes, and a new child matches the selector, the property will be updated. Content queries are set before the ngAfterContentInit callback is called.

Which are correct example for structural directive in Angular?

Structural directives are directives which change the DOM layout by adding and removing DOM elements. Angular provides a set of built-in structural directives (such as NgIf , NgForOf , NgSwitch and others) which are commonly used in all Angular projects.

What is difference between structural and attribute directives?

Attribute directives modify the appearance or behavior of DOM elements. Structural directives add or remove elements from the DOM. Structural directives are one of the most powerful features of Angular, and yet they're frequently misunderstood.


1 Answers

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.

like image 92
SeleM Avatar answered Sep 30 '22 03:09

SeleM