Angular routing configuration (preload configuration, lazy load configuration)

NgModule is the core of Angular module. Let's talk about it first.

1. Function of @ ngmodule:

  • The most fundamental meaning of NgModule is to help developers organize business code. Developers can use NgModule to organize closely related components, which is the most important.
  • NgModule is used to control whether components, instructions, pipes, etc. can be used. Components in the same NgModule are visible to each other by default. For external components, you can only see the contents exported by NgModule, that is, if the NgModule you define does not export any contents, even if the external user import s your module, You can't use anything defined in it.
  • NgModule is the smallest unit used in packaging. All @ NgModule and routing configurations will be checked during packaging. The underlying layer of Angular is packaged using webpack. Because Angular has already configured webpack for us, it is much easier for developers, otherwise they need to configure their own environment.
  • NgModule is the smallest unit for the Router to load asynchronously. The smallest unit that the Router can load is the module, not the component. Of course, it is allowed to put only one component in the module, which is done in many component libraries.

2.@NgModule structure description:

@NgModule({ 
  declarations: [], //Components, instructions and pipelines belonging to the current module
  imports: [], //Items that the current template depends on, i.e. external modules (including httpModule, routing, etc.)
  export:[],//Declare the application for other module s
  providers: [], //Inject service into current module
  bootstrap: []//Which component is started by default (only the root module can set the bootstrap attribute)
}) 
Copy code

3. Loading instructions

(1) The RouterModule object provides two static methods: forRoot() and forChild() to configure routing information.

  • forRoot() / / define the main routing information in the main module
  • forChild() ` ` / / used in the feature module (sub module)

(2) Lazy loading: loadChildren

Instead of adding the corresponding module to the AppModule, tell the Angular route to load the corresponding module according to the path configured by the loadChildren attribute through the loadChildren attribute. This is the specific application of the module lazy loading function. When the user accesses the / xxx / * * path, the corresponding module will be loaded, which reduces the size of loading resources when the application is started. The attribute value of loadChildren consists of three parts:

  • Relative path of Module to be imported
  • #Separator
  • Name of the exported module class

(3) Preload

In the case of lazy loading, when the route loads a module for the first time, sometimes the response is delayed. In this case, the preload strategy can be used to solve this problem.

Angular provides two loading strategies,

  • PreloadAllModules - preload
  • NoPreloading - no preloading (default).

The second parameter of RouterModule.forRoo() can add configuration options. One of the configuration options is preloadingStrategy configuration, which is a preload policy configuration.

//Use default preload - preload all modules
import { NgModule } from '@angular/core'; 
import { AppComponent } from './app.component'; 
import { routes } from './main.routing'; 
import { RouterModule } from '@angular/router'; 
import { PreloadAllModules } from '@angular/router'; 
@NgModule({ 
  declarations: [AppComponent], 
  imports: [ BrowserModule, RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) ], 
  providers: [], 
  bootstrap: [AppComponent] }) 
export class AppModule { }
Copy code

However, we prefer to control the module preloading by ourselves. In this case, we need to customize the preloading strategy

A. Custom - load all modules in 5 seconds

Create a new custom-preloading-strategy.ts file at the same level of the app

import { Route } from '@angular/router';
import { PreloadingStrategy } from '@angular/router';
import { Observable } from 'rxjs/Rx';

export class CustomPreloadingStrategy implements PreloadingStrategy {
    preload(route: Route, fn: () => Observable<boolean>): Observable<boolean> {
        return Observable.of(true).delay(5000).flatMap((_: boolean) => fn());
    }
}
Copy code

Inject in the providers of app.modules.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { routes } from './main.routing';
import { RouterModule } from '@angular/router';
import { CustomPreloadingStrategy } from './preload';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(routes, { preloadingStrategy:  CustomPreloadingStrategy })
  ],
  providers: [CustomPreloadingStrategy ],
  bootstrap: [AppComponent]
})
export class AppModule { }
Copy code

B. Custom - specifies the module preload

Create a new selective-preloading-strategy.ts file at the same level of the app build (you need to inject providers in app-routing.module.ts, and then set whether to preload the data defined in the route through additional parameters)

import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
@Injectable()
export class SelectivePreloadingStrategy implements PreloadingStrategy {
  preloadedModules: string[] = [];

  preload(route: Route, load: () => Observable<any>): Observable<any> {
    if (route.data && route.data['preload']) {
      return load();
    } else {
      return Observable.of(null);
    }
  }
}
Copy code

app-routing.module.ts (this file combines lazy loading with preloading)

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CanDeactivateGuard } from './guard/can-deactivate-guard.service';
import { SelectivePreloadingStrategy } from './selective-preloading-strategy'; // Preload
import { PageNotFoundComponent } from './not-found.component';
const appRoutes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full'},
{ path: 'mian', loadChildren: './main/mian.module#MainModule '}, / / lazy loading (the router configuration file and module file at this level do not need to introduce this component)
{ path: 'home', loadChildren: './home/home.module#Homemodule ', data: {preload: true}}, / / lazy load + preload
{ path: '**', component: PageNotFoundComponent } // Be careful to put it last
];
@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes,{
      enableTracing: true, // <-- debugging purposes only
      preloadingStrategy: SelectivePreloadingStrategy // Preload
    })
  ],
  exports: [
    RouterModule
  ],
  providers: [
    CanDeactivateGuard,
    SelectivePreloadingStrategy
  ]
})
export class AppRoutingModule { }
Copy code

4. Sub route creation steps (not created by instructions, directly manually)

(1) New home folder

Directory main

  • main.component.html
  • main.component.scss
  • main.component.ts
  • main.module.ts
  • main-routing.module.ts
  • main.service.ts
    • Catalog A
      • A.component.html
      • A.component.scss
      • A.component.ts
    • Catalog B
      • B.component.html
      • B.component.scss
      • B.component.ts

For example, there is an area in main.component.html above for putting sub views (I will talk about ideas first, and then put key codes. I won't repeat others)

<div>The area below is another route exit</div>
<router-outlet></router-outlet><!--Here, it is displayed by default according to the following routing configuration AComponent Content of component-->
Copy code

(1) In main-routing.module.ts, configure the route under the folder main, and you need to reference the component of each component (the component that needs to configure the route)

import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {MainComponent} from './main.component';
import{AComponent} from './A/A.component';
import{BComponent} from './B/B.component';
const mainRoute: Routes = [
  {
    path: '',
    component: MainComponent,
    data: {
      title: 'Interview appointment',
    },
    children: [
      {
        path: '',//If path is empty, it indicates the default route
        component: AComponent,
        data: {
          title: 'Big event',
        }
      },
      {
        path: 'activity',
        component: BComponent,
        data: {
          title: 'Medium activity',
        }
      }
    ]
  }
];


@NgModule({
  imports: [
    RouterModule.forChild(mainRoute)
  ],
  exports: [
    RouterModule
  ]
})
export class MainRoutingModule{
}
Copy code

(2) main.service.ts is generally used for http requests

import { AppService } from './../../app.service';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { PageData, ActivitysManage } from './model/activitys-manage';
import { BehaviorSubject } from 'rxjs';
import {PageDataBig, ActivitySmall, PageDataSmall } from './model/activitys-manage';
@Injectable()
export class MainService {
  
}
Copy code

If a component under the main folder wants to call MainService, it needs to import MainService in the ts file of the component

(3) Introduce components in main.module.ts (including itself, all components used in routing configuration files and routing modules)

import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { MainComponent } from './interview-appointment.component';
import { AComponent } from './A/A.component';
import { BComponent } from './B/B.component';
import { NgModule } from '@angular/core';
import { CoreFrameCommonModule } from '../../common/common.module';
import { MainRoutingModule } from './main-routing.module';
import { NgZorroAntdModule } from '../../zorro/ng-zorro-antd.module';
import { MainService } from './interview-appointment.service';
@NgModule({
  imports: [FormsModule,CoreFrameCommonModule, CommonModule, MainRoutingModule,NgZorroAntdModule],
  exports: [],
  declarations: [MainComponent,AComponent,BComponent],
  providers: [MainService],
})
export class MainModule{ }

Added by cainy1982 on Thu, 04 Nov 2021 05:57:35 +0200