How to avoid Angular using extra tag for a child component?

298 views Asked by At

Let's say I have parent and child component in Angular 12. For example, their templates looks like this:

Parent:

<h1>This is parent component</h1>
<div class="container">
    <div class="row">
        <div class="col">Foo</div>
        <ng-container>
            <app-child-component></app-child-component>
        </ng-container>
    </div>
</div>

I must use ng-container

Child:

<button>Click</button>

What angular does is create wrapper around child's component template, something like this:

    <h1>This is parent component</h1>
    <div class="container">
        <div class="row">
            <div class="col">Foo</div>
            <app-child-component>
                <button>Click</button>
            </app-child-component>
        </div>
    </div>

The desired effect I want to achieve is:

        <h1>This is parent component</h1>
        <div class="container">
            <div class="row">
                <div class="col">Foo</div>
                <button>Click</button>
            </div>
        </div>

I tried using attribute selector, i.e.

<div app-child-component></div>

But that adds extra div element I do not want. Attribute selectors can not be used on ng-template etc.

2

There are 2 answers

1
Debabrata909 On

You can use <ng-content></ng-content> on Child component Like :

<div>
   <ng-content></ng-content>
</div>

After That You can try:

 <div class="container">
    <div class="row">
        <div class="col">Foo</div>
        <app-child-component>
            <button>Click</button>
        </app-child-component>
    </div>
</div>     

Also you can check medium For more Detalis

0
kemsky On

Well, it is something that is very difficult to overcome in angular, it always creates host element.

There is one way to flatten hierarchy but it will add redundant node.

You have to use ng-template in app-child-component:

<ng-template #temlate><button>Click</button></ng-template>

Then inject ViewContainerRef to app-child-component.

Use ViewContainerRef to render template:

// i don't remember exact usage
viewContainerRef.createEmbeddedView(tempalteRef, null, viewContainerRef.length);

It will render template below app-child-component node, so the result will be like this:

<h1>This is parent component</h1>
<div class="container">
    <div class="row">
        <div class="col">Foo</div>
        <app-child-component></app-child-component>
        <button>Click</button>
    </div>
</div>

Then you can hide app-child-component node:

:host {
   display: none;
}