Implementing ComponentResolver (removing obsolete dynamic components)

I am trying to dynamically load components into another. Before beta 14, we used DynamicComponentLoader.loadIntoLocation, but since it is now deprecated and removed, we are looking for a new way to create components.

I saw a way ComponentResolver and ViewContainerRef, but I can not use this solution.

We use GoldenLayout to implement docking features on our web page. Thus, containers created by goldenlayout are dynamically inserted into the DOM using jQuery, so I cannot use it @ViewChildto get a link to ViewContainerRefand use it with the new method.

I found a way to do what I wanted with DynamicComponentLoader.loadAsRoot:

container.getElement().html(`<div id='component${Component.componentCount}'></div>`);
this.dynamicComponentLoader.loadAsRoot(Component,selector,this.injector)
    .then((componentRef:ComponentRef<Component>)=>{
            container.compRef = componentRef
            (<any>this.applicationRef)._loadComponent(componentRef);
            if(componentRef.instance.ngOnChanges){
                componentRef.instance.ngOnChanges();
            }
            return componentRef;    
    });

- , .getElement().html().

, DynamicComponentLoader, , - (<any>this.applicationRef)._loadComponent(componentRef);, "" , _loadComponent(), ApplicationRef.

, ViewContainerRef . , ( ).

, , , - .

.

.

Edit:

:

import { Directive,Component, OnInit ,ApplicationRef, ElementRef,ComponentRef,Type,Input,SimpleChange,DynamicComponentLoader,Injector} from '@angular/core';
import { TestaComponent } from '../testa/testa.component'
import { TestbComponent} from '../testb/testb.component'

declare var GoldenLayout : any;
declare var $ : JQueryStatic;

@Directive({
  selector: '[goldenlayout]',
})

export class GoldenLayoutComponent{

   @Input() glConfig : any;
    private myLayout : any; 

    static componentCount : number = 0;

    constructor(private applicationRef:ApplicationRef, private elementRef : ElementRef,private dynamicComponentLoader:DynamicComponentLoader,private injector: Injector) {}

    ngOnInit(){
        let goldenConfig = this.glConfig || {
            content:[{
                type:'row',
                content:[
                ]
            }]  
        };
        this.glConfig = goldenConfig;
        this.myLayout = new GoldenLayout(goldenConfig,this.elementRef.nativeElement);
        this.myLayout.registerComponent('TestAComponent',(container,componentState)=>{
            container.getElement().html("<div id='component" + GoldenLayoutComponent.componentCount +"'></div>");   
            this.dynamicComponentLoader.loadAsRoot(TestaComponent,"#component"+GoldenLayoutComponent.componentCount,this.injector)
            .then((componentRef:ComponentRef<TestaComponent>)=>{
                container.compRef = componentRef;
                (<any>this.applicationRef)._loadComponent(componentRef);
                componentRef.instance["buttonName"]= componentState.buttonName;
                if(componentRef.instance.ngOnChanges){
                    componentRef.instance.ngOnChanges();
                }
                return componentRef;

            });
            GoldenLayoutComponent.componentCount ++;
        });
        this.myLayout.registerComponent('TestBComponent',(container,componentState)=>{
            container.getElement().html("<div id='component" + GoldenLayoutComponent.componentCount +"'></div>");
            this.dynamicComponentLoader.loadAsRoot(TestbComponent,"#component"+GoldenLayoutComponent.componentCount,this.injector)
            .then((componentRef:ComponentRef<TestbComponent>)=>{
                container.compRef = componentRef;
                (<any>this.applicationRef)._loadComponent(componentRef);
                componentRef.instance["color"]= componentState.color;
                if(componentRef.instance.ngOnChanges){
                    componentRef.instance.ngOnChanges();
                }
                return componentRef;
            });
            GoldenLayoutComponent.componentCount ++;
        });

        this.myLayout.init();
        this.myLayout.on("itemDestroyed",(item)=>{
            if (item.container && item.container.compRef){
                this.disposeComp(item.container.compRef);
            }
        });
        this.myLayout.on("windowClosed",(item)=>{
            this.applicationRef.tick();
        });
    }

    disposeComp(comp : ComponentRef<any>){
        if (comp.instance && comp.instance.ngOnDestroy){
            comp.instance.ngOnDestroy();
            (<any>this.applicationRef)._unloadComponent(comp);
        }  
    }
    addComponent(name : string,option: string){
        let newComp : any;
        if(name == "TestAComponent"){
            newComp = {
                type: 'component',
                componentName: name,
                componentState: {buttonName : option}
            };
        }else{
            newComp = {
                type: 'component',
                componentName: name,
                componentState: {color : option}
            };
        }
     this.myLayout.root.contentItems[ 0 ].addChild(newComp);

    }
}

html:

<div style="margin:5px;">
    <button (click)='addComponent("TestAComponent",option)'>Spawn test a</button>
    <button (click)='addComponent("TestBComponent",option)'>Spawn test b</button>
    <input [(ngModel)]="option" type="text"/>
</div>
<div style="height:800px;" goldenlayout></div>

, , , container.getElement().html( ); addComponent.

DOM :

 <div>
        <button>Spawn test a</button>
        <button>Spawn test b</button>
        <input/>
    </div>
    <div goldenlayout>
       <div class="lm_goldenlayout lm_item lm_root"></div>
       <div class="lm_item lm_row"></div>
    </div>

. DOM :

<div>
    <button>Spawn test a</button>
    <button>Spawn test b</button>
    <input/>
</div>
<div goldenlayout>
   <div class="lm_goldenlayout lm_item lm_root"></div>
   <div class="lm_item lm_row">
       ...
       <div class="lm_items">
           <div class="lm_content">
               <div id="component0" _nghost-mip-3="">
                  <div _ngcontent-mip-3="">
                       <button _ngcontent-mip-3="">not set</button>
                  </div>
               </div>
           </div>
        </div>
        ...
   </div>
</div>

, div component0, lm_ goldenlayout.

+4

All Articles