angular配置懶加載路由的思路


前言

    本人記性不好,對於別人很容易記住的事情,我愣是記不住,所以還是靠爛筆頭來幫我長長記性。

 參考文章:https://blog.csdn.net/xif3681/article/details/84584317

正文

NgModule作為Angular模塊的核心,下面首先就來講一講。

1.@NgModule的作用:

  • NgModule 最根本的意義是幫助開發者組織業務代碼,開發者可以利用 NgModule 把關系比較緊密的組件組織到一起,這是首要的。
  • NgModule 用來控制組件、指令、管道等是否可以使用,處於同一個 NgModule 里面的組件默認互相可見,而對於外部的組件來說,只能看到 NgModule 導出( exports )的內容,也就是說,如果你定義的 NgModule 不 exports 任何內容,那么外部使用者即使 import 了你這個模塊,也沒法使用里面定義的任何內容。
  • NgModule 是打包時候用到的最小單位,打包的時候會檢查所有 @NgModule 和路由配置,Angular底層是使用webpack打包。因為Angular已經幫我們配置好了webpack,所以開發者輕松很多,否則就需要自己配置環境。
  • NgModule 是 Router 進行異步加載的最小單位,Router 能加載的最小單位是模塊,而不是組件。當然,模塊里面只放一個組件是允許的,很多組件庫都是這樣做的。

2.@NgModule結構說明:

@NgModule({ 
  declarations: [], //屬於當前模塊的組件、指令及管道
  imports: [], //當前模板所依賴的項,即外部模塊(包括httpModule、路由等)
  export:[],//聲明出應用給其他的module使用
  providers: [], //注入服務到當前模塊
  bootstrap: []//默認啟動哪個組件(只有根模塊才能設置bootstrap屬性)
})

3.懶加載說明

(1)RouterModule對象提供了兩個靜態的方法:forRoot()forChild()來配置路由信息。

  • forRoot()//在主模塊中定義主要的路由信息
  • forChild()//應用在特性模塊(子模塊)中

(2)懶加載:loadChildren

此處並沒有將對應的模塊加入到AppModule中,而是通過loadChildren屬性,告訴Angular路由依據loadChildren屬性配置的路徑去加載對應的模塊。這就是模塊懶加載功能的具體應用,當用戶訪問 /xxx/** 路徑的時候,才會加載對應的模塊,這減少了應用啟動時加載資源的大小。 loadChildren的屬性值由三部分組成:

  • 需要導入Module的相對路徑
  • #分隔符
  • 導出模塊類的名稱

(3)預加載

在使用懶加載的情況下,路由第一次加載某個模塊時,有時反應有延遲。這時就可以用預加載策略來解決這個問題。

Angular提供了兩種加載策略,

  • PreloadAllModules-預加載
  • NoPreloading-沒有預加載(默認)。

RouterModule.forRoo()第二個參數可以添加配置選項,配置選項中就有一個是preloadingStrategy配置,這個配置是一個預加載策略配置。

//使用默認預加載-預加載全部模塊
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 { }

但是,我們更喜歡自己去控制對模塊的預加載,這時就需要自定義預加載策略

A.自定義-5秒后加載所有模塊

在app組建的同級新建一個custom-preloading-strategy.ts文件

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());
    }
}

在app.modules.ts的providers中注入

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 { }

 

B.自定義-指定模塊預加載

在app組建的同級新建一個selective-preloading-strategy.ts文件(需要在app-routing.module.ts中的providers注入,然后在路由中定義的data通過附加參數來設置是否預加載

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);
    }
  }
}

 

app-routing.module.ts(此文件懶加載與預加載相結合)

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'; // 預加載
import { PageNotFoundComponent } from './not-found.component';
const appRoutes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full'},
{ path: 'mian', loadChildren: './main/mian.module#MainModule' }, // 懶加載(在這個層級的router配置文件及module文件都不需要引入該組建)
{ path: 'home', loadChildren: './home/home.module#HomeModule', data: { preload: true } }, // 懶加載 + 預加載
{ path: '**', component: PageNotFoundComponent } // 注意要放到最后
];
@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes,{
      enableTracing: true, // <-- debugging purposes only
      preloadingStrategy: SelectivePreloadingStrategy // 預加載
    })
  ],
  exports: [
    RouterModule
  ],
  providers: [
    CanDeactivateGuard,
    SelectivePreloadingStrategy
  ]
})
export class AppRoutingModule { }

 

4.子路由創建步驟(沒有靠指令創建,直接手動)

(1)新建主文件夾

目錄main

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

 

比如在上面main.component.html有個區域用於放子視圖(以下我都先講思路,再放關鍵代碼,其他不贅述)

<div>下面的區域是另一個路由出口</div>
<router-outlet></router-outlet><!--此處依照下面的路由配置,默認顯示AComponent組件的內容-->

(1)在main-routing.module.ts里面配置文件夾main下的路由,需要引用各組件的component(需要配置路由的組件)

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: '面試預約',
    },
    children: [
      {
        path: '',//path為空表示默認路由
        component: AComponent,
        data: {
          title: '大活動',
        }
      },
      {
        path: 'activity',
        component: BComponent,
        data: {
          title: '中活動',
        }
      }
    ]
  }
];


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

(2)main.service.ts一般用於放http請求

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 {
  
}

main文件夾下的組件如要調用MainService,需要在組件的ts文件引入MainService

(3)在main.module.ts中引入各組件(包括自身、路由配置文件所用到的所有組件以及路由的module)

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{ }

后續更新...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM