构建通用的angular项目
源代码参考
https://github.com/xif3681/angular-seed
先决条件
在开始之前,请确保你的开发环境已经包含了 Node.js® 和 npm 包管理器。
Node.js
Angular 需要 Node.js 的 8.x 或 10.x 版本。
- 要想检查你的版本,请在终端/控制台窗口中运行 node -v 命令。
- 要想安装 Node.js,请访问 nodejs.org。
第一步:安装 Angular CLI
你要使用 Angular CLI 来创建项目、创建应用和库代码,并执行多种开发任务,比如测试、打包和发布。
全局安装 Angular CLI。
要想使用 npm 来安装 CLI,请打开终端/控制台窗口,并输入下列命令:
npm install -g @angular/cli
CLI 命令参考手册
第二步:创建新的工作区和一个初始应用
ng new angular-tour-of-heroes
ng new 命令会创建一个 Angular 工作区目录,并生成一个新的应用骨架。 每个工作区中可以包含多个应用和库
工作区的配置文件 angular.json 位于此工作区的顶层。 在这里,你可以设置全工作区范围的默认值,并指定当 CLI 为不同目标构建项目时要用到的配置。
启动应用服务器link
进入工作区目录,并启动这个应用。
cd angular-tour-of-heroes ng serve --open
第三步:路由优化
一、路由配置
https://www.angular.cn/guide/router
添加 AppRoutingModule
在 Angular 中,最 好在一个独立的顶级模块中加载和配置路由器,它专注于路由功能,然后由根模块 AppModule 导入它。
按照惯例,这个模块类的名字叫做 AppRoutingModule,并且位于 src/app 下的 app-routing.module.ts 文件中。
使用 CLI 生成它。
命令行输入:
ng generate module app-routing --flat --module=app
--flat 把这个文件放进了 src/app 中,而不是单独的目录中。
--module=app 告诉 CLI 把它注册到 AppModule 的 imports 数组中
命令行输入:
ng generate component page-not-found
当你用 CLI 命令 ng new 创建新项目或用 ng generate app 命令创建新应用,请指定 --routing 选项。这会告诉 CLI 包含上 @angular/router 包,并创建一个名叫 app-routing.module.ts 的文件。 然后你就可以在添加到项目或应用中的任何 NgModule 中使用路由功能了。
比如,可以用下列命令生成带路由的 NgModule。
ng generate module my-module --routing
这将创建一个名叫 my-module-routing.module.ts 的独立文件,来保存这个 NgModule 的路由信息。 该文件包含一个空的 Routes 对象,你可以使用一些指向各个组件和 NgModule 的路由来填充该对象。
命令行输入:
ng generate module home --routing
ng generate module login --routing
命令行输入:
ng g c home/home
ng g c login/login
二、添加路由守卫
命令行输入:
ng g c home/homePage
ng generate module home/dashboard --routing
ng generate module home/manage --routing
ng g c home/dashboard
ng g c home/manage
CanActivate: 要求认证link
应用程序通常会根据访问者来决定是否授予某个特性区的访问权。 你可以只对已认证过的用户或具有特定角色的用户授予访问权,还可以阻止或限制用户访问权,直到用户账户**为止。
CanActivate 守卫是一个管理这些导航类业务规则的工具。
路由器可以支持多种守卫接口:
- 用CanActivate来处理导航到某路由的情况。
- 用CanActivateChild来处理导航到某子路由的情况。
- 用CanDeactivate来处理从当前路由离开的情况.
- 用Resolve在路由**之前获取路由数据。
- 用CanLoad来处理异步导航到某特性模块的情况。
在分层路由的每个级别上,你都可以设置多个守卫。 路由器会先按照从最深的子路由由下往上检查的顺序来检查 CanDeactivate() 和 CanActivateChild() 守卫。 然后它会按照从上到下的顺序检查 CanActivate() 守卫。 如果特性模块是异步加载的,在加载它之前还会检查 CanLoad() 守卫。 如果任何一个守卫返回 false,其它尚未完成的守卫会被取消,这样整个导航就被取消了。
命令行输入:
ng generate guard auth/auth
命令行输入:
ng generate service auth/auth
用户登录服务,该服务能让用户登录,并且保存当前用户的信息
auth.guard.ts:
auth.service.ts:
CanActivateChild:保护子路由link
你还可以使用 CanActivateChild 守卫来保护子路由。 CanActivateChild 守卫和 CanActivate 守卫很像。 它们的区别在于,CanActivateChild 会在任何子路由被**之前运行。
你要保护管理特性模块,防止它被非授权访问,还要保护这个特性模块内部的那些子路由。
https://www.angular.cn/guide/router#canactivatechild-guarding-child-routes
CanDeactivate:处理未保存的更改
命令行输入:
ng generate guard auth/can-deactivate
https://www.angular.cn/guide/router#candeactivate-handling-unsaved-changes
三、惰性加载路由配置
惰性加载路由配置link
把 home-routing.module.ts 中的 home 路径从 'home' 改为空路径 ''。
Router 支持空路径路由,可以使用它们来分组路由,而不用往 URL 中添加额外的路径片段。 用户仍旧访问 /home,并且 HomeComponent 仍然作为用来包含子路由的路由组件。
打开 AppRoutingModule,并把一个新的 home 路由添加到它的 appRoutes 数组中。
给它一个 loadChildren 属性(替换掉 children 属性),把它设置为 HomeModule 的地址。 该地址是 HomeModule 的文件路径(相对于 app 目录的),加上一个 # 分隔符,再加上导出模块的类名 HomeModule。
app-routing.module.ts:
home-routing.module.ts:
四、预加载:特性区的后台加载
AppModule 在应用启动时就被加载了,它是立即加载的。 而 AdminModule 只有当用户点击某个链接时才会加载,它是惰性加载的。
预加载是介于两者之间的一种方式。
要为所有惰性加载模块启用预加载功能,请从 Angular 的路由模块中导入 PreloadAllModules。
RouterModule.forRoot 方法的第二个参数接受一个附加配置选项对象。 preloadingStrategy 就是其中之一。 把 PreloadAllModules 添加到 forRoot 调用中:
这会让 Router 预加载器立即加载所有惰性加载路由(带 loadChildren 属性的路由)。
当访问 http://localhost:4200 时,/heroes 路由立即随之启动,并且路由器在加载了 HeroesModule 之后立即开始加载 CrisisCenterModule。
意外的是,AdminModule没有预加载,有什么东西阻塞了它。
CanLoad 会阻塞预加载
PreloadAllModules 策略不会加载被CanLoad守卫所保护的特性区。这是刻意设计的。
你几步之前刚刚给 AdminModule 中的路由添加了 CanLoad 守卫,以阻塞加载那个模块,直到用户认证结束。 CanLoad 守卫的优先级高于预加载策略。
如果你要加载一个模块并且保护它防止未授权访问,请移除 canLoad 守卫,只单独依赖CanActivate守卫。
五、自定义预加载策略
在大多数场景下,预加载每个惰性加载模块就很好了,但是有时候它却并不是正确的选择,特别是在移动设备和低带宽连接下。 你可能出于用户的测量和其它商业和技术因素而选择只对某些特性模块进行预加载。
使用自定义预加载策略,你可以控制路由器预加载哪些路由以及如何加载。
在这一节,你将添加一个自定义策略,它只预加载那些 data.preload 标志为 true 的路由。 回忆一下,你可以往路由的 data 属性中添加任何东西。
在 AppRoutingModule 的 crisis-center 路由中设置 data.preload 标志。
生成一个新的 SelectivePreloadingStrategyService 服务。
命令行输入:
ng generate service selective-preloading-strategy