使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码


Posted in Javascript onNovember 01, 2019

使用 Angular RouteReuseStrategy 缓存组件

Cache components with Angular RouteReuseStrategy

RouteReuseStrategy provider 允许我们控制 Angular 路由和组件生命周期的行为。

当我们在组件间切换的时候,Angular都会销毁上一个组件,并且创建一个新的组件。在大多数情况下,我们可能不想让它这样工作,因为每次加载一个组件,可能会有很多类似HTTP请求一样的昂贵的操作。

这时候就需要RouteReuseStrategy了。

RouteReuseStrategy是什么

RouteReuseStrategy接口声明了5个方法。

shouldReuseRoute

这个方法每次切换路由时都会被调用。future参数是将要离开的路由,curr参数是将要加载的路由。如果这个方法返回true,路由将不会跳转(意味着路由没有发生变化)。如果它返回false,则路由发生变化并且其余方法会被调用。

shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
  // 默认行为
  return future.routeConfig === curr.routeConfig;
}

shouldAttach

路由刚刚被打开,当我们加载到这个路由的组件上时,shouldAttach会被调用。一旦组件被加载这个方法都会被调用。如果这个方法返回trueretrieve方法将会被调用。否则这个组件将会被重新创建。

shouldAttach(route: ActivatedRouteSnapshot): boolean;

retrieve

shouldAttach方法返回true时这个方法会被调用。提供当前路由的参数(刚打开的路由),并且返回一个缓存的RouteHandle。如果返回null表示没有效果。我们可以使用这个方法手动获取任何已被缓存的RouteHandle。框架不会自动管理它,需要我们手动实现。

retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null;

shouldDetach

当离开当前路由时这个方法会被调用。如果返回truestore方法会被调用。

shouldDetach(route: ActivatedRouteSnapshot): boolean;

store

这个方法当且仅当shouldDetach方法返回true时被调用。我们可以在这里具体实现如何缓存RouteHandle。在这个方法中缓存的内容将会被用在retrieve方法中。它提供了我们离开的路由和RouteHandle

store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void;

示例

src/services/route-strategy.service.ts

 

import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';
export class RouteStrategyService implements RouteReuseStrategy {
 public static handlers: { [key: string]: DetachedRouteHandle } = {};
 public static deleteRouteSnapshot(path: string): void {
  const name = path.replace(/\//g, '_');
  if (RouteStrategyService.handlers[name]) {
   delete RouteStrategyService.handlers[name];
  }
 }
 /**
  * 判断当前路由是否需要缓存
  * 这个方法返回false时则路由发生变化并且其余方法会被调用
  * @param {ActivatedRouteSnapshot} future
  * @param {ActivatedRouteSnapshot} curr
  * @returns {boolean}
  * @memberof CacheRouteReuseStrategy
  */
 public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
  return future.routeConfig === curr.routeConfig
   && JSON.stringify(future.params) === JSON.stringify(curr.params);
 }
 /**
  * 当离开当前路由时这个方法会被调用
  * 如果返回 true 则 store 方法会被调用
  * @param {ActivatedRouteSnapshot} route
  * @returns {boolean}
  * @memberof CacheRouteReuseStrategy
  */
 public shouldDetach(route: ActivatedRouteSnapshot): boolean {
  return true;
 }
 /**
  * 将路由写入缓存
  * 在这里具体实现如何缓存 RouteHandle
  * 提供了我们离开的路由和 RouteHandle
  * @param {ActivatedRouteSnapshot} route
  * @param {DetachedRouteHandle} detachedTree
  * @memberof CacheRouteReuseStrategy
  */
 public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {
  RouteStrategyService.handlers[this.getPath(route)] = detachedTree;
 }
 /**
  * 路由被导航 如果此方法返回 true 则触发 retrieve 方法
  * 如果返回 false 这个组件将会被重新创建
  * @param {ActivatedRouteSnapshot} route
  * @returns {boolean}
  * @memberof CacheRouteReuseStrategy
  */
 public shouldAttach(route: ActivatedRouteSnapshot): boolean {
  return !!RouteStrategyService.handlers[this.getPath(route)];
 }
 /**
  * 从缓存读取cached route
  * 提供当前路由的参数(刚打开的路由),并且返回一个缓存的 RouteHandle
  * 可以使用这个方法手动获取任何已被缓存的 RouteHandle
  * @param {ActivatedRouteSnapshot} route
  * @returns {(DetachedRouteHandle | null)}
  * @memberof CacheRouteReuseStrategy
  */
 public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
  return RouteStrategyService.handlers[this.getPath(route)] || null;
 }
 private getPath(route: ActivatedRouteSnapshot): string {
  // tslint:disable-next-line: no-string-literal
  const path = route['_routerState'].url.replace(/\//g, '_');
  return path;
 }
}

src/app/app.module.ts:

import { RouteReuseStrategy } from '@angular/router';
import { RouteStrategyService } from '../services/route-strategy.service';

@NgModule({
  ...
  providers: [
    ...
    { provide: RouteReuseStrategy, useClass: RouteStrategyService }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

以上示例运行时会缓存所有路由组件。

实现比如标签页效果时,关闭标签页,调用RouteStrategyService中的deleteRouteSnapshot方法删除已缓存的页面即可。

这里可能会有个问题,如果你不想用这个路由缓存了,请务必删除掉app.module.ts中的providers,而不是将RouteStrategyService的shouldReuseRoute始终return true;这样会出现路由跳转页面不跳转的问题,原因暂时未知。

以下是运行效果图:

使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码

The end...
Last updated by Jehorn, 11/1/2019

总结

以上所述是小编给大家介绍的使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
点弹代码 点击页面任何位置都可以弹出页面效果代码
Sep 17 Javascript
JSON语法五大要素图文介绍
Dec 04 Javascript
使用JSLint提高JS代码质量方法分享
Dec 16 Javascript
jquery 选取方法都有哪些
May 18 Javascript
给before和after伪元素设置js效果的方法
Dec 04 Javascript
深入理解逻辑表达式的用法 与或非的用法
Jun 06 Javascript
jQuery自定义组件(导入组件)
Nov 08 Javascript
JavaScript函数节流和函数去抖知识点学习
Jul 31 Javascript
Vuex 使用 v-model 配合 state的方法
Nov 13 Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
Mar 29 Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
May 10 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
Sep 27 Javascript
vue实现计步器功能
Nov 01 #Javascript
详解小程序如何改变onLoad的执行时机
Nov 01 #Javascript
js canvas实现星空连线背景特效
Nov 01 #Javascript
jQuery鼠标滑过横向时间轴样式(代码详解)
Nov 01 #jQuery
微信小程序定义和调用全局变量globalData的实现
Nov 01 #Javascript
vue-router 中 meta的用法详解
Nov 01 #Javascript
VUE 解决mode为history页面为空白的问题
Nov 01 #Javascript
You might like
Ajax+PHP边学边练 之五 图片处理
2009/12/03 PHP
浅析Yii2 gridview实现批量删除教程
2016/04/22 PHP
Javascript 获取LI里的内容
2008/12/17 Javascript
使用Mootools动态添加Css样式表代码,兼容各浏览器
2011/12/12 Javascript
javascript仿qq界面的折叠菜单实现代码
2012/12/12 Javascript
AngularJS实现表单手动验证和表单自动验证
2015/12/09 Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
2016/07/05 Javascript
JS如何设置iOS中微信浏览器的title
2016/11/22 Javascript
详解jQuery中的DOM操作
2016/12/23 Javascript
使用BootStrap进行轮播图的制作
2017/01/06 Javascript
让bootstrap的carousel支持滑动滚屏的实现代码
2017/11/27 Javascript
微信小程序canvas绘制圆角base64图片的实现
2019/08/18 Javascript
layer ui插件显示tips时,修改字体颜色的实现方法
2019/09/11 Javascript
react用Redux中央仓库实现一个todolist
2019/09/29 Javascript
JS数组Reduce方法功能与用法实例详解
2020/04/29 Javascript
Antd中单个DatePicker限定时间输入范围操作
2020/10/29 Javascript
Python 可爱的大小写
2008/09/06 Python
python 网络编程常用代码段
2016/08/28 Python
itchat接口使用示例
2017/10/23 Python
Python 确定多项式拟合/回归的阶数实例
2018/12/29 Python
利用Python查看微信共同好友功能的实现代码
2019/04/24 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
python将logging模块封装成单独模块并实现动态切换Level方式
2020/05/12 Python
python 用pandas实现数据透视表功能
2020/12/21 Python
html5在移动端的屏幕适应问题示例探讨
2014/06/15 HTML / CSS
使用HTML5 Geolocation实现一个距离追踪器
2018/04/09 HTML / CSS
杰夫·班克斯男士服装网上商店:Jeff Banks
2019/10/24 全球购物
高中军训感言800字
2014/03/05 职场文书
毕业班联欢会主持词
2014/03/27 职场文书
百货商场楼层班组长竞聘书
2014/03/31 职场文书
经营理念标语
2014/06/21 职场文书
原生Js 实现的简单无缝滚动轮播图的示例代码
2021/05/10 Javascript
MySQL系列之十一 日志记录
2021/07/02 MySQL
i5-10400f处理相当于i7多少水平
2022/04/19 数码科技
解决MySQL报“too many connections“错误
2022/04/19 MySQL
python数据处理之Pandas类型转换
2022/04/28 Python