首頁  >  文章  >  web前端  >  淺談Angular中的預先載入配置、懶載入配置

淺談Angular中的預先載入配置、懶載入配置

青灯夜游
青灯夜游轉載
2021-11-05 10:13:552361瀏覽

這篇文章帶大家了解Angular中的路由配置,簡單介紹一下預先載入配置、懶載入配置,希望對大家有幫助!

淺談Angular中的預先載入配置、懶載入配置

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

1、@NgModule的作用:

  • #NgModule 最根本的意義是幫助開發者組織業務程式碼,開發者可以利用NgModule 把關係比較緊密的組件組織在一起,這是首要的。
  • NgModule 用來控制元件、指令、管道等是否可以使用,處於同一個NgModule 裡面的元件預設互相可見,而對於外部的元件來說,只能看到NgModule 匯出( exports )的內容,也就是說,如果你定義的NgModule 不exports 任何內容,那麼外部使用者即使import 了你這個模組,也沒辦法使用裡面定義的任何內容。
  • NgModule 是打包時候用到的最小單位,打包的時候會檢查所有 @NgModule 和路由配置,Angular底層是使用webpack打包。因為Angular已經幫我們配置了webpack,所以開發者輕鬆很多,否則就需要自己設定環境。
  • NgModule 是 Router 進行非同步載入的最小單位,Router 能載入的最小單位是模組,而不是元件。當然,模組裡面只放一個元件是允許的,很多元件庫都是這樣做的。 【相關教學推薦:《angular教學》】

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 &#39;@angular/platform-browser&#39;;
import { NgModule } from &#39;@angular/core&#39;;

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

@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 &#39;@angular/core&#39;;
import { PreloadingStrategy, Route } from &#39;@angular/router&#39;;
import { Observable} from &#39;rxjs/Observable&#39;;
import &#39;rxjs/add/observable/of&#39;;
@Injectable()
export class SelectivePreloadingStrategy implements PreloadingStrategy {
  preloadedModules: string[] = [];

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

app-routing.module.ts(此檔案懶載入與預先載入結合)

import { NgModule } from &#39;@angular/core&#39;;
import { RouterModule, Routes } from &#39;@angular/router&#39;;
import { CanDeactivateGuard } from &#39;./guard/can-deactivate-guard.service&#39;;
import { SelectivePreloadingStrategy } from &#39;./selective-preloading-strategy&#39;; // 预加载
import { PageNotFoundComponent } from &#39;./not-found.component&#39;;
const appRoutes: Routes = [
{ path: &#39;&#39;, redirectTo: &#39;home&#39;, pathMatch: &#39;full&#39;},
{ path: &#39;mian&#39;, loadChildren: &#39;./main/mian.module#MainModule&#39; }, // 懒加载(在这个层级的router配置文件及module文件都不需要引入该组建)
{ path: &#39;home&#39;, loadChildren: &#39;./home/home.module#HomeModule&#39;, data: { preload: true } }, // 懒加载 + 预加载
{ path: &#39;**&#39;, 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 &#39;@angular/core&#39;;
import {RouterModule, Routes} from &#39;@angular/router&#39;;
import {MainComponent} from &#39;./main.component&#39;;
import{AComponent} from &#39;./A/A.component&#39;;
import{BComponent} from &#39;./B/B.component&#39;;
const mainRoute: Routes = [
  {
    path: &#39;&#39;,
    component: MainComponent,
    data: {
      title: &#39;面试预约&#39;,
    },
    children: [
      {
        path: &#39;&#39;,//path为空表示默认路由
        component: AComponent,
        data: {
          title: &#39;大活动&#39;,
        }
      },
      {
        path: &#39;activity&#39;,
        component: BComponent,
        data: {
          title: &#39;中活动&#39;,
        }
      }
    ]
  }
];


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

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

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

main文件夹下的组件如要调用MainService,需要在组件的ts文件引入MainService

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

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

更多编程相关知识,请访问:编程视频!!

以上是淺談Angular中的預先載入配置、懶載入配置的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除