Lazy loading in angular is introduced to load the source and pages on demand. Concept is to group the feature in modules and when user load any page from that module, load the complete module only then rather than to load everything on application start.
Let's try to understand the concept with example: Say we have a website which have users, customers, products etc. For lazy Loading, we will keep all the users related information in Users module, similarly for the customers and products. When user will hit the home page, only basic information will be loaded and not the user, customer and product. When user will hit any page from any module that module will load at that time.
How can we acheive it: there are three main steps:
In this article we will see this with example:
Here we created two modules, customers and products, what it contains:
Similarly we will do for anyother modules, products.
I used-to to create components folder and keep all the compnent in that. It is not mandatory so we will not discuss that but you will not that folder in different places.
Let's create the customer module, Customer List Component: We will use hardcoded list of customers for example otherwise it need to come from database through server.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-customer-list',
templateUrl: './customer-list.component.html'
})
export class CustomerListComponent implements OnInit {
customerList: Array<any>;
constructor() { }
ngOnInit() {
this.customerList = [
{"id":100,"name":"John Smith","city":"Aylesbury","country":"Greece","zipcode":22101},
.................
]
}
}
Template for Customer List, to show the list of customers.
<h3>Customers List</h3>
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered">
<tr>
<th>ID</th>
<th>Name</th>
<th>City</th>
<th>Country</th>
<th style="white-space: nowrap;">Zip Code</th>
</tr>
<tr *ngFor="let item of customerList">
<td>{{item.id}}</td>
<td><a routerLink="{{item.id}}/detail">{{item.name}}</a></td>
<td>{{item.city}}</td>
<td>{{item.country}}</td>
<td>{{item.zipcode}}</td>
</tr>
</table>
</div>
</div>
Note the Name column is a link, which will open the detail page, so let's create the detail component, here is the code for customer detail component
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-customer-detail',
templateUrl: './customer-detail.component.html'
})
export class CustomerDetailComponent implements OnInit {
customerRecord: any;
// hard coded list of customers
customerList:Array<any> = [......];
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.params.subscribe(params => {
var id = params['id'];
this.getCustomer(id);
});
}
getCustomer(id){
this.customerRecord = this.customerList.filter(x=>x.id == id)[0];
}
}
Customer detail componente template (html), simply using bootstrap row and col-x to show the detail:
<h1>Customer Detail</h1>
<div class="row mb-2">
<td class="col-3"><strong>ID</strong></td>
<td class="col-9">{{customerRecord.id}}</td>
</div>
<div class="row mb-2">
<td class="col-3"><strong>Name</strong></td>
<td class="col-9">{{customerRecord.name}}</td>
</div>
<div class="row mb-2">
<td class="col-3"><strong>City</strong></td>
<td class="col-9">{{customerRecord.city}}</td>
</div>
<div class="row mb-2">
<td class="col-3"><strong>Country</strong></td>
<td class="col-9">{{customerRecord.country}}</td>
</div>
<div class="row mb-2">
<td class="col-3"><strong>Zip Code</strong></td>
<td class="col-9">{{customerRecord.zipcode}}</td>
</div>
If you want a defulat template, might be if you want to change the design or something, so simply create a container component with module name, in this case "Customer.Component.ts", and here is the complete code because we are using inline template here:
import { Component } from '@angular/core';
@Component({
selector: 'app-customers',
template: '<router-outlet></router-outlet>'
})
export class CustomersComponent{
constructor() { }
}
Note the router-outlet
, we need it to render the child component in it.
Nitll now there is nothing special about lazy loading, we just created three components in angular 6, so no need to explain any thing.
Now we need to create the routing for this module, for which we need to create a module ng g module customers-routing --flat -t -s
, here is the complete code for customers-routing module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';
import { CustomersComponent } from './customers.component';
import { CustomerListComponent } from './customer-list/customer-list.component';
import { CustomerDetailComponent } from './customer-detail/customer-detail.component';
const routes: Routes = [
{
path: '',
component: CustomersComponent,
children: [
{ path: ':id/detail', component: CustomerDetailComponent },
{ path:'', component: CustomerListComponent }
]
}
]
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
exports:[RouterModule],
declarations: [CustomersComponent, CustomerListComponent, CustomerDetailComponent ]
})
export class CustomersRoutingModule { }
What to nete here:
RouterModule.forChild(..)
Finally we need to create the ng g module customers --flat
, here is the complete code of Customers.Module.ts file:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CustomersRoutingModule } from './customers-routing.module';
@NgModule({
imports: [
CommonModule,
CustomersRoutingModule
],
declarations: []
})
export class CustomersModule { }
What to note here:
We need to create routing for application say it app-routing.module to create it run ng g module app-routing --flat
. Here is the code for app-routing.module.ts file:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';
import {AppComponent} from './app.component';
import { HomeComponent } from './components/home/home.component';
const mainRoutes: Routes = [
{
path:'customers',
loadChildren: '../app/components/customers/customers.module#CustomersModule'
},
{
path:'',
redirectTo:'',
pathMatch:'full',
component: HomeComponent
}
]
@NgModule({
imports: [
CommonModule,
RouterModule.forRoot(mainRoutes)
],
exports:[RouterModule],
declarations: [HomeComponent]
})
export class AppRoutingModule { }
Points to note here:
loadChildren
Path of the module file followed by # with module class name
{
path:'customers',
loadChildren: '../app/components/customers/customers.module#CustomersModule'
}
For default we use the home component
{
path:'',
redirectTo:'',
pathMatch:'full',
component: HomeComponent
}
RouterModule.forRoot(mainRoutes)
, note forRoot inplace of forChild which we used in our lazy loading module.We need use this app-routing.module into our app.module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Note we are not importing or decalring any module or component from the lazy loading features, just the appComponent to bootstrap the application and AppRoutingModule to load the basic resources.
For clarity, let's add app.component.ts and app.component.html template file:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent { }
// Template File
<div class="container">
<button routerLink="" class="btn btn-sm btn-link">Home</button>
<button routerLink="/customers" class="btn btn-sm btn-link">Customer</button>
<button routerLink="/products" class="btn btn-sm btn-link">Products</button>
<hr />
<router-outlet></router-outlet>
</div>
I used here buttons for exmaple, you can create a separate navigation component for top menu and use what ever html elements you want and import that.
Note the router-outlet
to render the rest of the pages and menu will be as it is.
Index.html file have nothing special except <app-root ></app-root>
I promise to copy the home.component so here the code for ts and html file
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: './home.component.html'
})
export class HomeComponent {
constructor() { }
}
// Html
<h1>Home</h1>
<hr>
<div class="row">
<div class="col-sm-6">
<h4>What is Lorem Ipsum?</h4>
<p>Lorem Ipsum is simply...</p>
</div>
<div class="col-sm-6">
<h4>Why do we use it?</h4>
<p>It is a long established...</p>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<h4>Where does it come from?</h4>
<p>Contrary to popular belief...</p>
</div>
<div class="col-sm-6">
<h4>Where can I get some?</h4>
<p>There are many variations of...</p>
</div>
</div>
Let's run the application see everything is working, run the command `ng serve'
Greate everything is working but I missed the bootstrap file to include. There are two way to use the bootstrap, either by using the CDN or by installing it.
If you are using CDN then open the style.css file and add
@import "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css";
Otherwise install it by npm i --save-dev bootstrap
, after installing it we need to reference it inside the angular.json
file:
"build": {
.........
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.css",
"src/styles.css"
]
}
We added two modules 1. Customer and 2. Products, we completed for customers so now we will create together complete products lazy loading module step be step and will practice it.
cd products
ng g component product-list -s
Create a dummy list of products say productList: Array
Similar to product list create product detail page and read the id from route and select a product from your dummy list ( you need to copy the dummy list here as well).
Create a products component in products folder ng g component products -s -t --flat
, here flat: means in current directory, t: means inline template, s: means inline style. means everything in products.component.ts file. After changing and removing unnesessary code, it will become:
import { Component } from '@angular/core';
@Component({
selector: 'app-products',
template: `<router-outlet></router-outlet>`
})
export class ProductsComponent { }
We need to create the routing for this module as well, so create a products-routing.module by using command ng g module products-routing
All the components created with ng commoand will automatically be imported into app.module.ts
file, copy and remove every import of product related components and add to product-routing.module.ts file:
import { Routes, RouterModule } from '@angular/router';
import { ProductsComponent } from './products.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
Create a variable say productRoutes and define the routes like this:
const productRoutes: Routes = [
{
path: '',
component: ProductsComponent,
children: [
{ path: ':id/detail', component: ProductDetailComponent },
{ path:'', component: ProductListComponent }
]
}
]
Inside the import add RouterModule.forChild(productRoutes)
and add all the components in declarations, now @NgModule will become
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(productRoutes)
],
declarations: [ProductsComponent, ProductListComponent, ProductDetailComponent ]
})
export class ProductsRoutingModule { }
One more file we need to add in this module call product.module.ts, create it by running the command ng g module products --flat
. After creating it, import our ProductRoutingModule and pass that in imports.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
//Added
import { ProductsRoutingModule} from './products-routing.module';
@NgModule({
imports: [
CommonModule,
ProductsRoutingModule // Added
],
declarations: []
})
export class ProductsModule { }
Open our app-routing.module.ts file and add routing for products (lazy loading). No need to import anything just add following lines after customers routing:
{
path:'products',
loadChildren: '../app/components/products/products.module#ProductsModule'
},
![]() |
Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
|
By Ali Adravi On 30 Jul, 18 Viewed: 5,808 |
Paging on table is the basic requirement and most of us look for some grid so it can provide the complete feature of paging and sorting but in Angularjs it is so easy that anyone can achieve it by writing some code. I checked and found most of the available code give the paging feature in for 1 to... By Ali Adravi On 14 Aug 2015 Viewed: 20,837
Cascading dropdown with angularjs is easier than MVC and ASP.Net. In Angularjs ng-change is the best event to hook the function to get the second dropdown list items. In this article, we will try to fill the state dropdown on selection change of country and then fill the city dropdown on change... By Ali Adravi On 06 Aug 2015 Viewed: 57,508
Add/Edid Customer in Modal Popup --- In previous article we discussed how to search, delete and show detail of customer and contact list. In this article we will try to open the modal popup to add new customer and edit an existing customer record. I divided article in two parts because of the... By Ali Adravi On 29 Jul 2015 Viewed: 19,499
Angularjs custom directives are the common to avoid the duplicate code, it is easy powerful and really nice. There are already too many directive have been created by experts but as a developer we need to write our own to achieve our specific goal. ng-model, ng-if, ng-show, ng-repeat all these are... By Ali Adravi On 29 Jul 2015 Viewed: 4,471
Search sort Insert update and delete are the basic features we need to learn first to learn any language, In this article we will try to create these features with Web API, bootstrap modal popup and ui.router. We will use enetity framework code first to save and retrieve data from database. We... By Ali Adravi On 28 Jul 2015 Viewed: 31,236