本站已关停,现有内容仅作科研等非赢利用途使用。特此声明。
查看: 2999|回复: 0
打印 上一主题 下一主题

[Angular2] Angular 2中NgModule,Lazy Loading与Route

[复制链接]
跳转到指定楼层
1#
发表于 2016-9-3 15:05:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 悟箜 于 2016-9-3 15:11 编辑

摘要

AngularJS 2.0 RC 5发布的同时Angular Router RC 1也同时发布,这其中包含了NgModule,也包含了Lazy Loading。今天我们就来看一下Angular 2 里的Lazy Loading。 文章中的代码已经整理上传到GitHub: https://github.com/WuKongW/Angular2_POC


就在我写这篇博客的时候,Angular2官方已经发布了RC 6,angular-router模块发布了RC 2.这次更新主要就是把废除的属性进行了移除跟代码重构,跟RC5相比并没有太大的变化,所以今天我们依旧用RC5来讲解,稍后我会统一把代码升级到RC 6.
Angular的主打就是单页应用(SPA),而且当我们的应用打成一个文件后体积在可承受范围之内时,我们并不需要做懒加载,这对一些中小型应用来说也是最佳选择,毕竟只需要一次加载就可以享受native的体验还是很高大上的。然而,当我们构建大型应用的时候,不得不考虑加载速度的问题,这个时候如果我们可以把某些可以拆分的模块单独打包,只有需要的时候再去加载,Lazy loading就显得格外重要了。
今天我们简单的讲一下在angular 2中怎么来做Lazy Loading,希望可以给大家一些启发或者帮助。

目录变化

老规矩我们先来看看这次跟上次的演示相比([Angular2] 添加Angular 2 router(路由)配置信息)我们项目的目录变动情况
这次的变化主要是我们把about封装成了模块(module),并且新建了一个叫blog的模块。细看名字还不一样,about文件夹前面有个+号??这代表这个模块是Lazy Loading的~哈哈~我们这里引入blog模块就是为了让大家跟好的看到lazy loading与直接加载的区别。
每个Module都单独有一个自己的routing文件,是专门负责这个模块的route的,这样就不会跟root app的routing混杂在一起了。


Blog 模块

因为blog module是在应用启动时直接下载下来的,所以我们先来看一下它吧。首先我们得 先来回顾一下我们在第二篇里([Angular2]创建简单的Angular 2 NgModule与Components)讲到关于module的理论,自行脑补下图~~

我们的Blog module就是一个简单的feature module,然后需要有自己的routing文件,大体就像下面这样:
  1. import { NgModule } from '@angular/core';

  2. import { BlogComponent }   from './blog.component';
  3. import { routing } from './blog.routing';

  4. @NgModule({
  5.     imports: [routing], /**  导入我们blog module自己routing */
  6.     declarations: [BlogComponent]/** 必须要声明这个module中要用到的component,directives,pipes */
  7. })
  8. export class BlogModule { }


  9. /**
  10. * 创建blog自己的routing文件
  11. */
  12. import { Routes, RouterModule } from '@angular/router';

  13. import { BlogComponent } from './blog.component';

  14. const routes: Routes = [
  15.   { path: 'blog', component: BlogComponent }/** 配置blog url的导航信息*/
  16. ];

  17. export const routing = RouterModule.forChild(routes);
复制代码
然后就想上图的模型中 一样,我们需要把blog module导入到app module中
app.module.ts
  1. import { NgModule } from '@angular/core';
  2. import { BrowserModule  } from '@angular/platform-browser';

  3. import { BlogModule } from './blog/blog.module';

  4. import AppComponent from './common/components/app.component';
  5. import { HomeComponent } from './common/components/index';
  6. import { routing } from './common/router/app.routing';

  7. @NgModule({
  8.     imports: [
  9.         BrowserModule,
  10.         BlogModule, /** 导入我们的Blog模块 */
  11.         routing,
  12.     ],
  13.     declarations: [AppComponent, HomeComponent],
  14.     bootstrap: [AppComponent],
  15. })

  16. export class AppModule { }
复制代码
这时候你会发现app的routing文件中并没有blog模块的链接信息??这是因为我们上面在blog模块自己routing文件中已经配置过了,而我们又把blog模块引入了app module, 所以当我们的应用启动时,不仅直接下载了blog模块的代码,blog模块的导航信息也会合并到app的主配置信息里,这样我们的应用就知道当我们点击blog按钮是应该显示哪个模块了~~

+About 模块

这里我们把之前写好的about component分离出来封装成了module,并且我们用它来演示Lazy Loading的过程。
跟Blog模块一样我们先来看一下about module的代码:
  1. import { RouterModule, Routes } from '@angular/router';

  2. import { HomeComponent } from '../components/index';

  3. const routes: Routes = [
  4.     { path: '', component: HomeComponent },
  5.     { path: 'about', loadChildren: 'app/+about/about.module' } /** loadChildren??这是什么鬼?? */
  6. ];

  7. export const routing = RouterModule.forRoot(routes);
复制代码
看完这段代码发现其实跟Blog模块没啥区别啊??是的,没有错,确实没什么区别,除了!!我们的routing信息写了一个空的path,而不是about,为什么呢?这是因为我们上面的app.routing.ts中已经定义了about了啊,也就是这一行
  1. { path: 'about', loadChildren: 'app/+about/about.module' }
复制代码
loadChilden又是神马??这就是lazy loading的关键所在了~loadChildren底层是调用了NgModuleFactoryLoader的load()方法来做的,但是这只是一个抽象类,并没有实现方法啊!!怎么做到lazy loading的!!!少年,淡定~~
如果你去查过官方的API文档你会发现,其实它还有另一个类叫SystemJsNgModuleLoader, 这又是个神马,点进去看看,原来这就是NgModuleFactoryLoader的实现类!那为什么叫SystemJsNgModuleLoader呢,难道跟systemJS有关??少年,你知道的太多了,哈哈~~没错,它的底层就是用的systemJS去加载的loadChildren中我们所写的路径,就跟我们在第一篇中配置的sysytem的信息去加载angular2的包一样一样的~~是不是瞬间觉得其实Lazy Loading看上去高大上,其实很简单的啊~~~哈哈哈
需要注意的就是,这里的loadChildren其实不止是string类型,还可以是function或者type类型。这里就留给大家自己去探索吧。
结语这里我们只是介绍了一下普通的module与Lazy Loading module在实际应用中的简单使用,并没有深入写很多复杂的route之类。因为Router其实是很大的一块,这也是问什么它在angular 2中是单独的一个模块,如果有机会的话,我会写一篇专门关于复杂router以及auth相关的文章。
最后,老规矩~~看一下我们的战利品~~
当我们点击About的时候,我们才去加载了跟About有关的代码:


文章中的代码已经整理上传到GitHub: https://github.com/WuKongW/Angular2_POC


ChinaGDG.com
回复

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表