• Angular


     Angular - 预加载延迟模块

    使用路由延迟加载中,我们介绍了如何使用模块来拆分应用,在访问到这个模块的时候, Angular 加载这个模块。但这需要一点时间。在用户第一次点击的时候,会有一点延迟。

    我们可以通过预加载路由来修复这个问题。路由可以在用户与其它部分交互的时候,异步加载延迟的模块。这可以使用户在访问延迟模块的时候更快地访问。

    本文将在上一个示例的基础上,增加预加载的功能。

    在上一节中,我们的根路由定义在 main.routing.ts,我们在 app.module.ts 中使用了根路由定义。

    需要注意的是,Home 组件是提前加载的。我们将在系统启动之后渲染这个组件。

    在 Angular 渲染 Home 组件之后,用户就可以与应用交互了,我们可以通过简单的配置在后台预加载其它模块。

    启用预加载

    我们在 forRoot 函数中,提供一个预加载的策略。

    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 { PreloadAllModules } from '@angular/router';
    
    @NgModule({
      declarations: [
        AppComponent,
        HomeComponent
      ],
      imports: [
        BrowserModule,
        RouterModule.forRoot(routes, { preloadingStrategy:  PreloadAllModules })
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

    这个 PreloadAllModules 策略来自 @angular/router,所以我们还需要导入它。

    定制预加载策略

    router 包中预定义了两个策略:

    5 秒之后加载模块

    但是,您可以自己定义一个定制的策略。这比您想的要更为简单。例如,您希望在应用初始化 5 秒之后加载其余的模块。

    您需要实现接口 PreloadingStrategy,我们定义一个 CustomPreloadingStrategy 的自定义策略类。

    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.module.ts 使用这个自定义策略。需要注意的是,您还需要在 prodivers 中添加这个类。以实现依赖注入。

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

    你会看到 在 5 秒钟之后,这个功能模块被自动加载了。

    加载指定模块

    我们还可以在路由中定义附加的参数来指定哪些模块进行预加载,我们使用路由定义中的 data 来提供这个附加的数据。

    import { Routes } from '@angular/router';
    // HomeComponent this components will be eager loaded
    import { HomeComponent } from './home/home.component';
    
    export const routes: Routes = [
        { path: '', component: HomeComponent, pathMatch: 'full' },
        { path: 'shop', loadChildren: './shop/shop.module#ShopModule', data: {preload: true} },
        { path: '**', component: HomeComponent }
    ];

    然后,我们定义新的加载策略。

    import { Observable } from 'rxjs/Rx';
    import { PreloadingStrategy, Route } from '@angular/router';
    
    export class PreloadSelectedModules implements PreloadingStrategy {
        preload(route: Route, load: Function): Observable<any> {
            return route.data && route.data.preload ? load() : Observable.of(null);
        }
    }

    最后,在 app.module.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 { PreloadSelectedModules } from './preload.module';
    
    @NgModule({
      declarations: [
        AppComponent,
        HomeComponent
      ],
      imports: [
        BrowserModule,
        RouterModule.forRoot(routes, { preloadingStrategy:  PreloadSelectedModules })
      ],
      providers: [PreloadSelectedModules ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

    此时,可以看到,模块直接被预加载了。即使您点击链接,也不会再有新的请求发生。

    其它资源:

  • 相关阅读:
    JS伪3D 图形透视效果
    源码安装apache及配置转发
    SpringSecutiry权限管理手册
    解决SMARTFORMS 中table 控件单行跨页的问题
    Cluster Table
    uva-133 The Dole Queue
    第三届蓝桥杯C++本科B组决赛解题报告(更新中)
    uva-673 Parentheses Balance
    VS2010不能编译SQLServer2005的Microsoft.SQLServer.ManagedDTS.dll的解决方法
    IOS设计模式学习(21)享元
  • 原文地址:https://www.cnblogs.com/haogj/p/7649707.html
Copyright © 2020-2023  润新知