2

I have a component template:

<div #wrapper></div>

In my .ts code I have:

@ViewChild("wrapper", {read: ViewContainerRef}) wrapper:ViewContainerRef;
.
.
.
ngAfterViewInit() {
  this.wrapper.createComponent(SomeComponent);
}

I want to make an instance of SomeComponent and add it to #wrapper div.

All works as expected except for SomeComponent is being rendered after <div #wrapper></div> and not as its child (which I would expect).

What am I missing? How to render SomeComponent within div?

8
  • 1
    This is the expected behaviour, there's no "clean" way to do what you want but you can try this : How to dynamically create component inside child component in Angular? Commented May 5, 2024 at 20:18
  • 1
    @TibèreB. yes, that's what I ended up doing: getting a reference of adiv element and apending a components element as a child (but using renderer). Commented May 5, 2024 at 20:42
  • can't you use <ng-container #placeToRender> inside a div as a place to render? Commented May 5, 2024 at 23:12
  • @Andrei Perhaps. How would I do that? In particular, how would I get the reference to it from the code and how would I apply component to it dynamically? Commented May 6, 2024 at 4:22
  • Andrei's solution is to add an ng-container element isinde of the div where you want to create the component, the template from your example would become : <div><ng-container #wrapper></ng-container></div> Commented May 6, 2024 at 10:34

2 Answers 2

1

Create a directive that's nothing but a ViewContainerRef, then use it with an ng-template in your actual component's template.

Directive:

@Directive({
    selector: '[someComponentHost]',
    standalone: true
})
export class SomeComponentHostDirective {
    constructor (public viewContainerRef: ViewContainerRef) {}
}

Your component template:

<div class="wrapper">
   <ng-template someComponentHost></ng-template>
</div>

Your component:

@ViewChild(SomeComponentHostDirective) host!: SomeComponentHostDirective;

const viewContainerRef = this.host.viewContainerRef;
viewContainerRef.createComponent(SomeComponent);

So you're using a view container, on an ng-template that won't render, inside the div you actually want to wrap your component.

Sign up to request clarification or add additional context in comments.

Comments

0

for angular 17 and higher:

<div>
  <ng-container #wrapper></ng-container>
</div>

and in ts file:

  import {ViewContainerRef, viewChildren} from '@angular/core';

  public wrapper= viewChildren('wrapper', { read: ViewContainerRef });

  ngAfterViewInit() {
    this.wrapper.createComponent(SomeComponent);
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.