angulardynamictabstransclusionangular2-ngcontent

Angular: ViewContainer isn't inserting component adjacent to anchor element, but nesting within the component itself


I have created a tab view, with the following structure:

<tabs>
        <ul #getVCRefHERE >
            <li>tab1</li>
            <li>tab2</li>
        </ul>

        <tab>
            <ng-content></ng-content> <!--screen for tab2 -->
        </tab>
        <tab>
            <ng-content></ng-content> <!--content for tab1 -->
        </tab>
</tabs>

I create each component: tabs,tab,and the component placed in the ng-content. place. The issue is when I insert at the end of the ViewContainer(it uses ul as it's anchor element) the sequential tabs are nest inside of the tab like this:

<tabs>
            <ul #postionVCRef>
                <li>tab1</li>
                <li>tab2</li>
            </ul>

            <tab>
                <ng-content></ng-content> <!--screen for tab1 -->
                <tab>
                    <ng-content></ng-content> <!--content for tab2 -->
                </tab>
            </tab>

    </tabs>

It is fancy trick, but not helpful. When I insert at position 0 this weird nesting doesn't occur, but the tabs are inserted in opposite order than they were created which causes me issues later in my app.

The code that creates the tab with its projectable node looks like this:

// Tab == SubContainer,  Tabs == Container
    makeComp(component: Type<DynamicComponent>){
        let compFactory =this.compFR.resolveComponentFactory(component);
        let compRef = this.viewContainer.createComponent(compFactory);

        let length =this.viewContainer.length - 1;
        console.log(length)
        let subFactory = this.compFR.resolveComponentFactory(SubContainer); 
        let subRef = this.viewContainer.createComponent(subFactory,length,undefined,[[compRef.location.nativeElement]]);
        subRef.instance.title = compRef.instance.name;
        this.subList.push(subRef.instance);

      }

I feel the issue is probably in how I am creating the ng-content(projectable nodes). Unfortunately, I am unaware why the viewContainer appears to be using the tab's ng-content as the anchor element to insert the next tab.

I would really appreciate someone with better understanding of viewContainer to tell me why this might be occurring. Here is my sample app demonstrating this nesting behavior.


Solution

  • Use this code to insert siblings of element where you apply selector of component. At your component:

    import { HostListener,ComponentRef,EventEmitter,OnInit,ElementRef, Injectable ,Component,Input,Output,ViewContainerRef,ViewChild  } from '@angular/core';
    

    At constructor

        constructor(private _vcr: ViewContainerRef,private _eref: ElementRef) {
    }
    

    At class

    @ViewChild('Date') Date;
    ngAfterViewInit() {
           this._vcr.createEmbeddedView(this.Date);  
        }
    

    at template

    <ng-template #Date>
    // Your Html
    </ng-template>
    

    The natural behavior of using child selector is to insert the code of child template html inside the selector tags which are used in parent component. So we have to use createEmbeddedView function of ViewContainerRef [ Parent HTML Element]. If you want to provide some html with in selector tag fro parent to child then use inside child template.