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 包中预定义了两个策略:
- 不预加载 nopreloading
- 预加载所有模块 preloadallmodules
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 { }
此时,可以看到,模块直接被预加载了。即使您点击链接,也不会再有新的请求发生。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。