question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Content lifecycle on conditional transclusion

See original GitHub issue

I’m submitting a …

[x] bug report

Current behavior When you use conditional directive on <ng-content> content component are correctly added/removed to the DOM depending on the condition but they have weird lifecycle. They have the same lifecyle than the parent, meaning when they are removed from the DOM the component instance is kept and reuse when they are added again to the DOM.

Expected behavior Content component should have their own lifecycle corresponding to the conditional. Instantiate when adding to the DOM and destroyed when removed from the DOM.

Minimal reproduction of the problem with instructions Component using transclusion like that :

@Component({
  selector: 'conditional-content'
  template: `
    <ng-content *ngIf="condition"></ng-content>
    <button (click)="condition = !condition">toggle</button>
  `
})

Let’s say you do :

<conditional-content>
    <some-component></some-component>
</conditional-content>

then <some-component> will have the same lifecycle has conditional-content.

Plunker example: https://plnkr.co/edit/KdyKG6qtiA9eoqxJOIep

What is the motivation / use case for changing the behavior? When content component rely on ElementRef because it becomes null when component is removed from the DOM.

  • Angular version: 2.0.X 2.X.X

  • Browser: [all]

  • Language: [all]

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:4
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

9reactions
tboschcommented, Dec 3, 2016

This is by design. The lifecycle of a component is always tied to the place where the component was declared. I.e. not at the place where the <ng-content> is used. To conditionally create / destroy components together with content projection, use <template> and ngTemplateOutlet.

1reaction
ghetolaycommented, Nov 28, 2016

From the docs :

A component has a lifecycle managed by Angular itself.

Angular creates it, renders it, creates and renders its children, checks it when its data-bound properties change, and destroys it before removing it from the DOM.

So from my understanding I don’t expect a component instance to exist if it’s not part of the DOM.

Any component using ElementRef on constructor, ngOnInit() or ngAfterViewInit() will face a null nativeElement if the initial condition is false. Or even if the initial condition is true and you listen for an event, once the condition will turn to false, you won’t listen anymore to that event because the component’s element has been removed. And even if the condition becomes true again you won’t never listen to the event anymore because none of constructor, ngOnInit nor ngAfterViewInit() will be called again.

I took ElementRef as an example but I guess we could find more scenarios.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Content projection - Angular
Components that use conditional content projection render content only when specific conditions are met. Single-slot content projectionlink. The most basic form ...
Read more >
Content Projection (Transclusion) | by Paul Chesa - Medium
Content projection encourages reusability of component designs and functionality by showing different content in a similar structure of a component.
Read more >
Angular directive with conditional transclusion & discrete ...
Life cycle though is take care by $parent relations. When the superior (placed higher in the HTML DOM hierarchy) directive is destroyed it...
Read more >
Woes of conditional text and topichead elements (DITA best ...
The first is that it conflicts with the notion of the separation of content and form, and the separation of data and metadata....
Read more >
How to check whether ng-content exists [duplicate]
Closed last year. Suppose i have simple Bootstrap panel component with multiple transclusion slots. Template example: <div class=" ...
Read more >

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found