6

Can we load component dynamically in Angular 2 using it's selector?

Lets say we have a component like below,

 @Component({
    moduleId: module.id,
    selector: 'my-component',
    templateUrl: 'my-component.html',
    styleUrls: ['my-component.css']   
 })
 export class MyComponent{
 }

Can we load this dynamically into a container using it's selector my-component

<div #container ></div>

LoadComponent(selector: string){
    // Load using selector?
}

There may be a need of exporting components in the NgModule and importing the NgModule where we want to load it.

Not sure on how to achieve this, any pointers in right direction would be very helpful.

Thanks in advance!!

Madhu Ranjan
  • 17,334
  • 7
  • 60
  • 69
  • You might find this answer useful: http://stackoverflow.com/a/38888009/6680611 – cartant Sep 20 '16 at 05:12
  • @cartant The post is talking about creating a component on the fly, my question is if I have imported a module and want to load the component from that without knowing about which module it belongs to, how to do that. So when we use the component in html it is instantiated by compiler right, so something similar should be there. – Madhu Ranjan Sep 20 '16 at 05:18
  • Are you wanting to create a HTML template dynamically? If that's the case, I think the linked answer is relevant. If not, I've misunderstood your question. – cartant Sep 20 '16 at 05:27
  • Please check this plunker https://plnkr.co/edit/1oVsAjv46UStOZOzQRzu?p=preview. – yurzui Sep 20 '16 at 07:48
  • @yurzui: Thanks, that is in right direction, however i am looking for a way were I don't need to know the Module type, Is there a way in which we can get all Modules which are already compiled and is available for use dynamically in which we can check if a particular component is available? – Madhu Ranjan Sep 20 '16 at 14:02
  • 2
    You can experiment like https://plnkr.co/edit/m6UJz6Xb72uzIBiNipDV?p=preview – yurzui Sep 20 '16 at 16:07
  • @yurzui Thanks, I will look into this. – Madhu Ranjan Sep 20 '16 at 16:12
  • Seems there are no public methods which can do it today – yurzui Sep 20 '16 at 16:15
  • @yurzui what If I want to bind the data using Input, like ? – deen Feb 13 '17 at 15:33
  • @MadhuRanjan is there a way to load selector dynamically in html – Vignesh May 19 '17 at 12:30
  • How can we pass module to loadComponent function from html using webpack – Vignesh May 23 '17 at 06:14
  • Why down vote? Is the question not following guideline please let me know what is that who did down vote did not like?. Please maintain integrity at Stack Overflow. – Madhu Ranjan May 23 '17 at 14:11

3 Answers3

1

Well I was able to resolve this using below,

constructor(private _compiler: Compiler) {}

loadComponent = (selector: string, module: any): void => {  
  this._compiler.compileModuleAndAllComponentsAsync(module).then(_module => {
    let _componentFactories = _module.componentFactories.filter(_c => {
      // here I am using the selector
      return _c.selector === selector;
    });

    // check if component is available in the module
    if (!!_componentFactories && _componentFactories.length > 0) {
       self.testComponentContainer.clear();
       self.testComponentContainer.createComponent(_componentFactories[0]).instance;                    
    }
  });
}

Hope it helps someone.. !!!

Madhu Ranjan
  • 17,334
  • 7
  • 60
  • 69
1

suppose your index.html has . then in your .ts or js file, when condition ready, do this: var div = document.getElementById('container');

    div.innerHTML = "<my-component></my-component>"
Feng Zhang
  • 1,698
  • 1
  • 17
  • 20
-2

You can load any component dynamically using ComponentResolver.
Add following html node into parent template

<div #node></div>

And your component will look like

import { Component, ViewContainerRef, ViewChild, ComponentFactory, ComponentResolver } from '@angular/core';
import { MyComponent} from 'components/my.component';

@Component({
selector: 'app-home',
template: `<h2>Home</h2>
    <div #node></div>
 `
})

export class HomeComponent implements OnInit {
@ViewChild("node", { read: ViewContainerRef }) nodeView;
instance: MyComponent
constructor(private componentResolver: ComponentResolver) {
}

ngOnInit(): void {
    this.componentResolver.resolveComponent(MyComponent)
        .then((factory: ComponentFactory<MyComponent>) => {
             this.instance = this.nodeView.createComponent(factory);
        });
    }
}