Wednesday, June 19, 2019

ui router in angular with lazy loading

You can use UI-Router in angular 2, angular 4, angular 5, angular 6, angular 7, angular 8, etc for advance routing to display States and nested substates, Path, Query, and Hash parameters, Named multiple Views, etc

By using ui-router you can manage angular routing very accuracy and easily and by using you can also use routing inheritance. here will make some basic code by using ui router with lazy loading.

for use, install @uirouter module by using the following command

npm install @uirouter/angular --save

Demo :
Directory structure in app directory
=>(src/app)
app.module.ts
app.states.ts
app.component.css
app.component.ts
app.component.html

=>(src/app/book)
book.component.spec.ts
book.component.css
book.component.html
book.module.ts
book.component.ts

=>(src/app/home)
home.module.ts
home.component.html
home.component.css
home.component.ts
home.component.spec.ts

=>(src/app/footer)
footer.component.css
footer.component.html
footer.component.ts
footer.component.spec.ts

=>(src/app/header)
header.component.css
header.component.spec.ts
header.component.html
header.component.ts

=>(src/app/empty)
empty.module.ts
empty.component.css
empty.component.ts
empty.component.spec.ts


=>app.states.ts (src/app/app.states.ts)
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';

import { Ng2StateDeclaration, loadNgModule } from "@uirouter/angular";

export let APP_STATES: Ng2StateDeclaration[] = [
  {
    name: 'app',
    //abstract: true,
     views: {
      "header": { component: HeaderComponent},
      "footer": { component: FooterComponent},
    }
  },
  {
    name: 'app.home.**',
    url: '/',
    loadChildren: './home/home.module#HomeModule'
  },
  {
    name: 'app.books.**',
    url: '/books',
    loadChildren: './book/book.module#BookModule'
  }
];

In the above app.states file we have make a routing path with Lazy Loading Feature Modules like a home module and books module.

If the header and footer will be available in may pages, we have defined it in app path and inherit it in home and books page.

here we should not make a separate module of header and footer because it is common for all/many pages.

=>app.module.ts (src/app)
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, NgModuleFactoryLoader, SystemJsNgModuleLoader } from '@angular/core';
import {UIRouterModule} from "@uirouter/angular";
import { APP_STATES } from './app.states';

import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';


@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
  ],
  imports: [
  BrowserModule
  UIRouterModule.forRoot({ states: APP_STATES, useHash: false, otherwise: { state: 'app.home' } })
],
  providers: [
    { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
above module is the main module in where we import defined app.states.

=>app.component.html (src/app)
<div>
    <ui-view name="header"></ui-view>
 
    <div style="width: 100%;border: 1px solid #dcdcdc;clear: both;margin-bottom: 5px;">
     
        <div style="border: 1px solid #dcdcdc;float: left;">
              <ui-view name="content"></ui-view>
        </div>
    </div>
    <ui-view name="footer"></ui-view>
</div>
by ui-view with the name, it will be put particular state component as per views

=>header (src/app/header)

Make header component and html file which will be displayed in the header section.

=>footer (src/app/footer)

Make footer component and html file which will be displayed in the footer section.

=>empty.module.ts (src/app/empty)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { EmptyComponent } from './empty.component';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [EmptyComponent],
})
export class EmptyModule { }

=>empty.component.ts (src/app/empty)

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-empty',
  //templateUrl: './empty.component.html',
  template: '',
  styleUrls: ['./empty.component.css']
})
export class EmptyComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


=>home.module.ts (src/app/home)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HomeComponent } from './home.component';
import {UIRouterModule} from "@uirouter/angular";

import { Ng2StateDeclaration, Transition } from "@uirouter/angular";

let APP_SUB_STATES: Ng2StateDeclaration[] = [
// A state for the 'app.contact' submodule.
{
    name: "app.home",
    url: "/",
    views: {
      "content@":  { component: HomeComponent },
    },
}
];

@NgModule({
  imports: [
    CommonModule,
    UIRouterModule.forChild({ states: APP_SUB_STATES })
  ],
  declarations: [HomeComponent]
})
export class HomeModule { }

here we have to define routing again because in app.states.ts we have defined it as feature lazyloading module.

here only content view will be change and header and footer will remain as it is.

if you want to remove header and footer then you must have to do as below steps.

{
    name: "app.home",
    url: "/",
    views: {
      "header@": { component: EmptyComponent},
      "footer@": { component: EmptyComponent},
      "content@":  { component: HomeComponent },
    },
}

here you have to make EmptyComponent shared module is shared module and use its component in header and footer view.
make sure in empty component make html file as blank or don't use templateUrl and assign template to blank like as bellow.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-empty',
  template: '',
  styleUrls: ['./empty.component.css']
})
export class EmptyComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

for more info check the book module code where we have remove header and footer page.

=>home.component.ts (src/app/home)
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


=>home.component.html (src/app/home)
<p>
  welcome to home page....
</p>


=>book.module.ts (src/app/book)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {UIRouterModule} from "@uirouter/angular";

import { Ng2StateDeclaration, Transition } from "@uirouter/angular";

import { EmptyModule } from '../empty/empty.module';
import { EmptyComponent } from '../empty/empty.component';

let APP_SUB_STATES: Ng2StateDeclaration[] = [
// A state for the 'app.contact' submodule.
{
    name: "app.books",
    url: "/books",
    views: {
      "header@": { component: EmptyComponent},
      "footer@": { component: EmptyComponent},
      "content@":  { component: BookComponent },
    },
}
];

@NgModule({
  imports: [
    CommonModule,
    UIRouterModule.forChild({ states: APP_SUB_STATES })
  ],
  declarations: [BookComponent]
})
export class BookModule { }


=>book.component.ts (src/app/book)
import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'app-book',
  templateUrl: './book.component.html',
  styleUrls: ['./book.component.css']
})
export class BookComponent implements OnInit {

constructor() { }

 ngOnInit() {}

}

=>book.component.html (src/app/book)
<p>
  welcome to book page....
</p>

I think it's clear how to use ui router in angular with lazy loading / lazy load in any angular version like as angular 2, angular 4, angular 5, angular 6, angular 7, angular 8 , etc.

No comments:

Post a Comment