Angular Resolver 教程

Photo by Kristine Weilert on Unsplash

声明

本教程是 Angular 路由快速教程的后续章节。假设您已经拥有了一些 Angular

相关的基础路由知识,了解了 Angular 路由模块常见路由组件以及路由匹配的

基本方法,尚不清楚的同学建议复习一下相关知识

Resolver —— 路由的新机制

在很多时候,我们会在组件初始化的时候(ngOnInit 消息钩子)中预先抓取数

据。但是假如数据抓取耗时较长,会导致在组件渲染的时候数据还没拿到渲染

的数据(多数情况会在控制台报错)。为了避免这种情况,就要用到 Resolver

在路由到组件之前做数据的预抓取。

同时,相比于直接在组件中注入服务,Resolver 还可以将数据抓取与其他业务

逻辑分离开来,更加利于项目的维护和扩展。这种做法也被称为遵循 “单一职责

原则(single responsibility principle )”。

Angular(6+) 中配置一个 Resolver 也非常简单。只需在路由匹配表中,为

某一条路由的 resolve 属性指定一个满足某种格式的服务,就可以轻松实现数

据的预抓取。

创建 Resolver

首先要明确 Resolver 本身是一个服务,因此创建服务(service)的那些东西

一个都不能少啦,比如 @Injectable() 修饰符。同时,一个 Resolver 需要实现

@angular/router 中的 Resolve 接口,并实现其中的resolve 方法。我们可以

在这里完成数据的预抓取,并返回一个 Observable 对象。

把 Resolver 添加到模块

还是那句话,因为我们的 Resolver 是个服务,所以服务那套还是不能少呀。这

里,我们在对应模块的 providers 中添加 HomeResolver。

最后一步!

创建完我们的 Resolver 服务之后,我们就可以在路由匹配表中指定这个服务。

值得注意的是,这边也是通过键值对的形式( heros: HomeResolver )来指定

我们的 Resovler 服务。这种形式是不是很眼熟?没错,这和 Angular的 DI 机

制如出一辙。通过这样的配置形式,可以让我们方便地在不同的开发阶段替换

这个 Resolver,而不需要修改额外的代码,实现了代码的解耦。

大工告成

目前为止,我们的 HomeResolver 已经全部配置完毕。现在,我们就可以在组

件中安心地取到我们想要获得的数据了。

很简单,只需在组件中注入 Angular 路由组件中的 ActivatedRout 服务,并对

其 data 属性调用 subscribe 方法就可以完成数据的获取。当然值得注意的是,

我们需要调用 data.heros(我们在 resolve 属性中指定的键)来获取预抓取的

数据。

陷阱

Resolver 中一旦你想返回一个 Subject,那么必须注意这个 Subject 是可结束

的,而不是循环触发某项事件。否则 Resolver 会一直等待。一般情况下,可以

用 Filter 函数中的 take 等来强制让某 Subject 变成可结束的。

在线例子

参考链接

Understanding Resolvers in Angular

Angular 6|7 Router: Resolve (Route Resolver) Example

Angular Router: Route Resolvers

Resolving Data in Angular 2, 4, and 5; refactoring components; and moving to ngrx/store

发表评论

电子邮件地址不会被公开。 必填项已用*标注