简体   繁体   中英

How to load dynamically a component in angular 4 in the parent component

I'm creating template components to be loaded in the parent component depending on what response I get from the server. I'll give you a brief example of what I'm trying to do in pseudo code.

This is my html parent component:

<div class="parent-container">
    <div *ngIf="template1"> (load template1.component) </div>
    <div *ngIf="template2"> (load template2.component) </div>
    etc...
</div>

then I would have the different components (for sake of brevity I will just list one)

<div class="child-container">
    <div> {{userName}} </div>
    <div> {{contactNo}} </div>
    <div> {{address}} </div>
</div>

so on ngInit the parent makes an http request to the server and gets a value. Depends on the value in the parent, I should be able to load the child template into the parent and display it. So, once loaded, the page would look like this:

<div class="parent-container">
    <div class="child-container">
        <div> {{userName}} </div>
        <div> {{contactNo}} </div>
        <div> {{address}} </div>
    </div>
</div>

Is it possible in angular? How can i create it? Thanks

[ edit ]

I implemented what dee zg suggested, this is the code:

@ViewChild(HostDirective) host: HostDirective;

OnNgInit(){}

//switch will be a response from a server 
selector(switch){
    switch(switch) { 
       case 'component1': { 
         this.loadComponent(Component1);
         break; 
      }  
      default: { 

         break; 
      } 
   } 

  }

  loadComponent(component){   


    var componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);
    var viewContainerRef = this.host;
    this.viewContainerRef.clear();
    var componentRef = this.viewContainerRef.createComponent(componentFactory);

    (componentRef.instance);

  }

this is what is inside my host

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

@Directive({
  selector: '[host]',
})
export class HostDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

and the html

<ng-template host></ng-template>

funny thing is that if whatever is inside loadComponent will be loaded into OnInit, then it will work. If I call it from loadComponent I will get that host is undefined.

in template:

<ng-template #yourComponentHost></ng-template>

in component:

@ViewChild('yourComponentHost', { read: ViewContainerRef })
  yourComponentHost;
.
.
.
const componentFactory = this._componentFactoryResolver.resolveComponentFactory(YourComponentType1);
    const viewContainerRef = this.yourComponentHost;
    viewContainerRef.clear();
    const componentRef = viewContainerRef.createComponent(componentFactory);

    const yourComponentType1Instance = (<YourComponentType1>componentRef.instance);

From here, you have an access to your component through yourComponentType1Instance . Of course, you'll do your own switch logic in resolveComponentFactory to use component you need based on conditions you want.

It's a little bit confusing what you are looking for. Because with your problem, why don't you create component for you child.

<div class="parent-container">
    <div *ngIf="template1"> <template1 [myData]="myData"></template1> </div>
    <div *ngIf="template2"> <template2 [myData]="myData"></template2> </div>
    etc...
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM