Angular 5.0 学习8:Angular路由复用策略 (切换页面内容不丢失,保持原来状态)

一、引言

路由在执行过程中对组件无状态操作,即路由离退时组件状态也一并被删除;当然在绝大多数场景下这是合理的。进入组件时会执行 ngOnInit() 里面的初始化方法,使页面保持最开始的状态。但有些需求需要切换页面的时候,再切换回来该页面时保持原来的状态。此时我们就需要 Angular 的RouteReuseStrategy 贯穿路由状态并决定构建组件的方式。

二、RouteReuseStrategy

RouteReuseStrategy :路由复用策略,提供了几种办法通俗易懂的方法:

shouldDetach 是否允许复用路由
store 当路由离开时会触发,存储路由
shouldAttach 是否允许还原路由
retrieve 获取存储路由
shouldReuseRoute 进入路由触发,是否同一路由时复用路由

三、使用步骤

1.新建 simple-reuse-strategy.ts,网上已经有大佬写好了,我稍微修改了一下, 路由复用策略默认对所有路由复用 可通过给路由配置项增加data: { keep: true }来进行选择性使用。

// simple-reuse-strategy.ts
// tslint:disable
import {RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle} from '@angular/router';

export class SimpleReuseStrategy implements RouteReuseStrategy {

  _cacheRouters: { [key: string]: any } = {};

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    // 默认对所有路由复用 可通过给路由配置项增加data: { keep: true }来进行选择性使用
   // {path: 'search', component: SearchComponent, data: {keep: true}},
    if (!route.data.keep) {
      return false;
    } else {
      return true;
    }
  }

  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    // 按path作为key存储路由快照&组件当前实例对象
    // path等同RouterModule.forRoot中的配置
    this._cacheRouters[route.routeConfig.path] = {
      snapshot: route,
      handle: handle
    };
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    // 在缓存中有的都认为允许还原路由
    return !!route.routeConfig && !!this._cacheRouters[route.routeConfig.path];
  }

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    // 从缓存中获取快照,若无则返回null
    if (!route.routeConfig || route.routeConfig.loadChildren || !this._cacheRouters[route.routeConfig.path]) return null;
    return this._cacheRouters[route.routeConfig.path].handle;

  }

  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    // 同一路由时复用路由
    return future.routeConfig === curr.routeConfig;
  }


}

2.将策略注册到模块当中:

import {RouteReuseStrategy, RouterModule, Routes} from '@angular/router';
import {SimpleReuseStrategy} from './simple-reuse-strategy';
providers: [
  /*路由复用策略*/
  { provide: RouteReuseStrategy, useClass: SimpleReuseStrategy }
]

3.使用路由复用策略后,ngOnInit 的方法不会再执行,这个时候需要把 ngOnInit的方法写在NavigationEnd里

// 任意一个页面组件
import {NavigationEnd, Router} from '@angular/router';
constructor(private router: Router) {
    this.router.events
      .filter((event) => event instanceof NavigationEnd)
      .subscribe((event: NavigationEnd) => {
      // 这里需要判断一下当前路由,如果不加的话,每次路由结束的时候都会执行这里的方法,这里以search组件为例
        if (event.url === '/search') {
          /*在这写需要执行初始化的方法*/
          this.search();
        }
      });
  }

4.额外问题
退出系统后,换另外一个用户登录,组件状态也会保留,这是不合理的。

 shouldAttach(route: ActivatedRouteSnapshot): boolean {
    // 在路由是login的时候清空缓存
    if(route.routeConfig['path'] === 'login'){
      this._cacheRouters = {};
    }
    // 在缓存中有的都认为允许还原路由
    return !!route.routeConfig && !!this._cacheRouters[route.routeConfig.path];
  }
    原文作者:zhiyu
    原文地址: https://segmentfault.com/a/1190000014944087
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞