乐趣区

使用路由复用来实现返回上一页面内容不刷新

问题:

最近遇到的问题是我们在一个查询列表页面上对该页面的的某条内容进行编辑或者新增之后再跳回的话,我们的原页面便会重新加载,这个不是很人性化,为此我们想要实现的效果是,在编辑和修改完成之后,返回原界面时原内容保留。实现效果如下所示。

编辑前

编辑后

在这里我们使用了一种叫做路由复用的机制来实现。

解决方式:

大概的原理是,一般情况下,在路由离开时就会销毁该路由的组件,再次跳转时会重新初始化,调用 nginit()方法,但是我们现在是需求是保留路由的原状态,为此我们需要重写 RouteReuseStrategy 接口,该接口实现路由复用策略。

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

在该项目中我们的具体实现代码如下

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 true;} else {return false;}
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        // 在懒加载的时候使用,data.key 存储路由快照 & 组件当前实例对象
        // path 等同 RouterModule.forRoot 中的配置
        this._cacheRouters[route.data.key] = {
            snapshot: route,
            handle: handle
        };
    }

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

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

    }

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

对于要服用的路由我们如下使用

{path: '', component: InstrumentCategoryIndexComponent, data: {keep: true, key:'instrumentCategory'}},

# 遇到的问题

  1. 第一个问题是如何使得跳转后页面的查询和分页信息不变,只更新数据。

解决方法:
由于使用了路由服用机制之后,便不执行 nginit 的方法了所以我们在构造函数中加上对路由的监听事件,当路由切换的时候我们使用原有的分页和查询参数对数据进行更新。

    params;
    constructor(
        private instrumentCategoryService: InstrumentCategoryService,
        @Inject('DEFAULT_SIZE_CONFIG') private size: number,
        private adminComponent: AdminComponent,
        private instrumentAliasService: InstrumentAliasService,
        private instrumentSpecificationService: InstrumentSpecificationService,
        private router: Router
    ) {
        // 路由复用之后重新加载数据
        this.router.events.subscribe(() => {if (this.params) {this.page();
           }
        });
    }
    
    ngOnInit() {
        // 初始化参数
        this.params = {
            page: 0, // 默认是第 0 页
            size: this.size, // 获取默认的每页大小
            name: null, // 姓名
            subjectCategory: null, // 学科类别
        };

        this.page();}
  1. 惰性加载下路由复用的失效

当使用路由服用的策略之后, 出现按照之前的策略失效,产生如下错误。这个问题花了很久也没解决后来找喜硕帮忙解决,原因是我们使用了惰性加载,在惰性加载的时候 route.routeConfig.path 加载就为空,所以在存储的时候后产生错误。

后来的解决方案如下,我们在路由的数据上新增一个 key 值用这个 key 的值来存储我们的复用的路由如上代码所示。

退出移动版