Dynamic Component Loading

By | | Updated : 2019-02-16 | Viewed : 476 times

angular dynamic component loading

Usually when we writing the application, sometimes dynamic component loading is extremely required. So dynamic component loading is the one of the highly needed in angular based application. We will learn here how to code for Dynamic component loading in Angular.

Here code snippet is for displaying the details of pizza in the dashboard. Here we have two type of pizzas, which will be displayed here. On click of button, the details will be fetched and displayed.

Please create the project by using below Angular CLI command. Once you create the project you need to create the two type of components here.

create angular project by using below given angular cli comand
ng new Dynamic-Component-Loading-App

We will discuss the code files one by one. Please create the remaining components by using below given commands in angular CLI.

CLI Commands for creating components
ng g component NonvegPizza --inlineTemplate=true --inlineStyle=true --entryComponent=true --spec=false
ng g component VegPizza    --inlineTemplate=true --inlineStyle=true --entryComponent=true --spec=false
Angular CLI commands for service and class
ng g service Pizza --skipTests=true
ng g class Pizza --skipTests=true
app.component.html
<div style="text-align:center">
    <h1>
        Welcome to {{ title }}!
    </h1>
    <button style="margin-bottom:10px;" (click)="ShowVegPizzas(vegPizza)">ShowVegPizzas</button>
    <button style="margin-bottom:10px;" (click)="ShowNonVegPizzas(nonVegPizza)">ShowNonVegPizzas</button>
    <br />
    <ng-template #pizzaContainer>
    </ng-template>
</div>

app.component.ts
import { 
	Component,ViewChild,ViewContainerRef,
	ComponentFactoryResolver,ComponentRef,
	ComponentFactory, 	OnInit } from '@angular/core';
	
import { NonvegPizzaComponent } from './nonveg-pizza/nonveg-pizza.component';
import { VegPizzaComponent } 	from './veg-pizza/veg-pizza.component';
import { PizzaService }         from './pizza.service';
import { Pizza }            	from './pizza';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
	
	title = 'Dynamic-Component-Loading-App';
	vegPizza: Pizza[];
	nonVegPizza: Pizza[];

	ngOnInit() {
	 this.vegPizza = this.pizzaService.getVegPizzasDetails();
	 this.nonVegPizza = this.pizzaService.getNonVegPizzasDetails();
	}

	@ViewChild('pizzaContainer', { read: ViewContainerRef }) entry: ViewContainerRef;
	constructor(private resolver: ComponentFactoryResolver,private pizzaService: PizzaService) { }

	ShowVegPizzas(pizza) {
		this.entry.clear();
		const factory = this.resolver.resolveComponentFactory(VegPizzaComponent);
		const componentRef = this.entry.createComponent(factory);
		componentRef.instance.vegPizza = pizza;
		
	}
	ShowNonVegPizzas(pizza) {
		this.entry.clear();
		const factory = this.resolver.resolveComponentFactory(NonvegPizzaComponent);
		const componentRef = this.entry.createComponent(factory);
		componentRef.instance.nonVegPizza = pizza
		
	}
}
app.module.ts
import { BrowserModule } 	from '@angular/platform-browser';
import { NgModule } 		from '@angular/core';

import { AppComponent } 		from './app.component';
import { NonvegPizzaComponent } from './nonveg-pizza/nonveg-pizza.component';
import { VegPizzaComponent } 	from './veg-pizza/veg-pizza.component';
import { PizzaService } 		from './pizza.service';


@NgModule({
  declarations: [
    AppComponent,
    NonvegPizzaComponent,
    VegPizzaComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [PizzaService],
  bootstrap: [AppComponent],
  entryComponents: [NonvegPizzaComponent,VegPizzaComponent]
})
export class AppModule { }

Please find the above given code for AppComponent and its html template. The AppComponent will be initialized when the tag has been interpreted. While creating the object of AppComponent, the ComponentFactoryResolver and PizzaService has been initialized. After creating of the object of AppComponent, two variables (vegPizza, nonVegPizza) will be initialized with values in ngOnit method/function. ComponentFactoryResolver, is one of the core class for resolving the component.

The resolved component will be injected into the parent component by @ViewChild decorator. You can find here click here to know about how to use the @ViewChild. So, while injecting Child component, the child’s template will be displayed. So here we can see the vegPizza and nonVegPizza details. But both components will be loaded in one container dynamically.

The resolved component will be injected into the parent component by @ViewChild decorator. You can find here click here to know about how to use the @ViewChild. So, while injecting Child component, the child’s template will be displayed. So here we can see the vegPizza and nonVegPizza details. But both components will be loaded in one container dynamically.

pizza.service.ts
import { Injectable }          from '@angular/core';
import { Pizza }               from './pizza';

@Injectable()
export class PizzaService {

  getVegPizzasDetails() {
    return [
      new Pizza({type: 'Veg',name: 'Veggi Paradise', price: '10$'})    
    ];
  };
  
  getNonVegPizzasDetails() {
    return [
      new Pizza({type: 'Veg',name: 'Non Veg Supreme', price: '10$'})   
    ];
  }
}
pizza.ts
import { Type } from '@angular/core';

export class Pizza {
  constructor( public data: any) {}
}
veg-pizza.component.ts
import { Component, Input } from '@angular/core';
import { Pizza }            from '../pizza';

@Component({
  selector: 'app-veg-pizza',
  template: `
    <span>{{vegPizza[0].data.type}}</span>   |
	<span>{{vegPizza[0].data.name}}</span>   |
	<span>{{vegPizza[0].data.price}}</span>
  `,
  styles: []
})
export class VegPizzaComponent {

  @Input() vegPizza: Pizza;
}
nonveg-pizza.component.ts
import { Component, Input } from '@angular/core';
import { Pizza }            from '../pizza';

@Component({
  selector: 'app-nonveg-pizza',
  template: `
    <span>{{nonVegPizza[0].data.type}}</span>   |
	<span>{{nonVegPizza[0].data.name}}</span>   |
	<span>{{nonVegPizza[0].data.price}}</span>
  `,
  styles: []
})
export class NonvegPizzaComponent {

	@Input() nonVegPizza: Pizza;

}

Code Explanation: Both components are defined in entry Components of AppModule. So, these components will be loaded without consider any ref angular tag in the html template. Usually, the angular tags interpretation will make creation of component object and loading. In order to interpret , the AppComponent object will be generated and resulted html template will be placed in the . But when you define some of the components as in entryComponents of AppModule, then these components objects will be created and template will not be loaded into DOM.

So here when we click on the buttons (ShowVegPizzas and ShowNonVegPizzas) then appropriate function will be executed in the AppComponent. Here we are taking the help of ComponentFactoryResolver to get the object and resulted html template will be loaded in the container pizzaContainer. In app.component.html, we used ng-template directive. It will be useful to load html dynamically.

Leave A Reply