In Angular 2, components are the main way we build and specify elements and logic on the page. And we typically load it as a tag in the markup which contains some conditions to make it load dynamic.

But there are cases where we don’t know the DOM structure at compile time. In such cases we have to add components on demand in arbitrary locations, hence we use DynamicComponentLoader to load a component dynamically. In these cases we’ll be able to instantiate a component and attaching it to a View at a specified location.

DynamicComponentLoader consist of three methods which can be used to load a component into DOM.

loadAsRoot :

It creates an instance of a Component and attaches it to the first element in the DOM that matches the component’s selector.

It takes minimum of three argument the first one is component which is to be loaded.The second argument is selector which shows where the component should be loaded into DOM and the third one is injector which is used to instantiate the component.

plunker



selector: ‘my-app’,

template: `

<button (click)=”form()”>View Form</button>

<div id=”form”>Welcome..! Here form component will be loaded.

</div>

`

}) @Component ({selector: ‘my-app’,template: ` View Form Welcome..! Here form component will be loaded. }) export class App {

constructor(public dcl:DynamicComponentLoader,

public _injector:Injector) {

}

form(){

this.dcl.loadAsRoot(Form,”#form”,this._injector)

}

}

In the above code ‘form’ component is loaded in the div element having id ‘form’. Optionally we can provide onDispose callback which notify when this component instance is destroyed.

It returns a promise as ComponentRef representing the newly created component. One more thing to note about loadAsRoot is that when the component is loaded it will replace the content present in that element i.e. when form component will be loaded the text ‘Welcome..! Here form component will be loaded.’ will be replaced by form component.

loadIntoLocation :

It creates an instance of a component and attaches it to a View Container. loadIntoLocation takes at least three arguments, the first is component which will be loaded. Second argument is the targeted Component Instance which is specified via its hostLocation ElementRef. The third one is Template Variable used to specify the location where the component is to be loaded.

plunker



selector: ‘my-app’,

template: `

<button (click)=”form()”>View Form</button>

<div #form>Welcome..! Here form component will be loaded.</div>

<div>Form will be loaded above this.</div>

`

})

export class App {

public component: any;

constructor(public dcl:DynamicComponentLoader, public _injector:Injector, public _elementRef: ElementRef) {

}

form(){

if(this.component != undefined){

this.component.then((componentRef:ComponentRef) => {

componentRef.dispose();

return componentRef;

});

}

this.component = this.dcl.loadIntoLocation(Form, this._elementRef, “form”);

}

} @Component ({selector: ‘my-app’,template: ` View Form Welcome..! Here form component will be loaded. Form will be loaded above this. })export class App {public component: any;constructor(public dcl:DynamicComponentLoader, public _injector:Injector, public _elementRef: ElementRef) {form(){if(this.component != undefined){this.component.then((componentRef:ComponentRef) => {componentRef.dispose();return componentRef;});this.component = this.dcl.loadIntoLocation(Form, this._elementRef, “form”);

Here in the example ‘Form’ component will be loaded below the div element having template variable ‘#form’. Unlike loadAsRoot it loads the component by it’s selector name in the resulting DOM.

Once a component is loaded it can be destroyed using dispose method. Otherwise every time new instance will be created without destroying previous instances.

loadNextToLocation :

loadNextToLocation method takes minimum of two argument the first is component which is to be loaded and second is elementRef which specifies that the component will be loaded below it.

plunker.



selector: ‘my-app’,

template: `

<button (click)=”form()”>View Form</button>

<div>Welcome..! Here form component will be loaded.</div>

<div> Form will be loaded below this. </div>

`

})

export class App {

public component: any;

constructor(public dcl:DynamicComponentLoader, public _injector:Injector, public _elementRef: ElementRef) {

}

form(){

if(this.component != undefined){

this.component.then((componentRef:ComponentRef) => {

componentRef.dispose();

return componentRef;

});

}

this.component = this.dcl.loadNextToLocation(Form, this._elementRef);

}

} @Component ({selector: ‘my-app’,template: ` View Form Welcome..! Here form component will be loaded. Form will be loaded below this. })export class App {public component: any;constructor(public dcl:DynamicComponentLoader, public _injector:Injector, public _elementRef: ElementRef) {form(){if(this.component != undefined){this.component.then((componentRef:ComponentRef) => {componentRef.dispose();return componentRef;});this.component = this.dcl.loadNextToLocation(Form, this._elementRef);

In the above example, ‘form’ component will be loaded as a tag after the app component specified by ‘elementRef’.

Additionally we can use provider in these methods to send data to the component which is to be loaded dynamically as shown below:

let binding = Injector.resolve([

new Provider(“id”, {useValue: id})

]);

this.dcl.loadIntoLocation(Detail, this._elementRef,"detail", binding);

We can fetch the desired data in Detail Component as :