Angular Resolver 教程

Photo by Kristine Weilert on Unsplash

声明

本教程是 Angular 路由快速教程的后续章节。假设您已经拥有了一些 Angular 相关的基础路由知识,了解了 Angular 路由模块常见路由组件以及路由匹配的基本方法,尚不清楚的同学建议复习一下路由相关知识

Resolver —— 路由的新机制

在很多时候,我们会在组件初始化的时候(ngOnInit 消息钩子)中预先抓取数据。但是假如数据抓取耗时较长,会导致在组件渲染的时候数据还没拿到渲染的数据(多数情况会在控制台报错)。为了避免这种情况,可以使用 ngIf 指令,让 Angular 在数据加载完成之后对页面进行渲染,也可以用到 Resolver 在路由到组件之前做数据的预抓取。

相比于直接在组件中注入服务,Resolver 可以将数据抓取与其他业务逻辑分离开来,更加利于项目的维护和扩展。这种做法也被称为遵循 “单一职责原则(single responsibility principle )”。

Angular 配置一个 Resolver 也非常简单。只需在路由匹配表中,为某一条路由的 resolve 属性指定一个满足某种格式的服务,就可以轻松实现预抓取。

创建 Resolver

首先要明确 Resolver 本身是一个服务,因此创建服务(service)的那些东西一个都不能少啦,比如 @Injectable() 修饰符。同时,一个 Resolver 需要实现 @angular/router 中的 Resolve 接口,并实现其中的 resolve 方法。我们可以在此方法中完成数据预抓取,同时需要返回一个 Observable 对象。

把 Resolver 添加到模块

还是那句话,因为我们的 Resolver 是个服务,所以服务那套还是不能少。这里,我们在对应模块的 providers 中添加 HomeResolver。

最后一步!

创建完我们的 Resolver 服务之后,我们就可以在路由匹配表中指定这个服务。通过 heros: HomeResolver 的形式来指定 Resolver 服务,可以让我们在开发的不同阶段根据需求随时替换这个 Resolver,而不需要修改额外的代码,实现了代码的解耦。

大工告成

目前为止,我们的 HomeResolver 已经全部配置完毕。现在,我们就可以在组件中安心地取到 Resolver 中预抓取的数据了。

这里,我没只需在组件中注入 Angular 路由组件中的 ActivatedRout 服务,并对其 data 属性调用 subscribe 方法就可以完成数据的获取。值得注意的是,我们需要调用 data.heros(在 resolve 属性中指定的键)来取得 hero 对象。

陷阱

Resolver 中一旦你想返回一个 Subject,那么必须注意这个 Subject 是可结束的,而不是循环触发某项事件。否则 Resolver 会一直等待。一般情况下,可以用 RxJS 的Filter 函数,如 take 等来强制让某 Subject 变成可结束的。

在线例子

参考链接

Understanding Angular Route Resolvers

Understanding Resolvers in Angular

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

Angular Router: Route Resolvers

发表评论

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