Angular 2 implementing RouteReuseStrategy

送分小仙女□ 提交于 2019-11-30 23:55:21

I have same problem and was trying for last one week. Seems like it works fine for me now. Main challenge is defining a unique key for any given routes. I find RouteReuseStrategy become bit complex to understand and define key for each route when your configure you app with child routing and lazy loading. I try to explain my understanding and I hope this information helpful.

RouteReuseStrategy
I was trying to figure out the RouteReuseStrategy method calls and parameter details to generate unique key and come up with following diagram by debugging my application. Noticed sometimes stage parameters passed to method calls and try to ignore those parameters in RouteReuseStrategy implementation.

CustomReuseStrategy

RouteReuseStrategy Implementation:

/* tslint:disable */
import {ActivatedRouteSnapshot, DetachedRouteHandle, Params, RouteReuseStrategy} from "@angular/router";

interface RouteStorageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class CustomReuseStrategy implements RouteReuseStrategy {
    storedRoutes: { [key: string]: RouteStorageObject } = {};

    getFurthestDecendantParams(route: ActivatedRouteSnapshot, sum: any): ActivatedRouteSnapshot {
        if (route.children.length > 0) {
            let child: ActivatedRouteSnapshot = route.children[0];
            sum.sum                           = sum.sum + this.sumParams(child.params);
            return this.getFurthestDecendantParams(child, sum);
        }
        return route;
    }

    sumParams(params: Params): string {
        return Object.keys(params).reduce((param, key) => {
            return param + params[key];
        }, "");
    }

    calcKey(route: ActivatedRouteSnapshot) {
        let paramKey = {
            sum: ""
        }
        if (route.children.length > 0) {
            this.getFurthestDecendantParams(route, paramKey).params;
        } else {
            paramKey.sum = this.sumParams(route.params);
        }
        if (paramKey.sum != "") {
            paramKey.sum = "_" + paramKey.sum;
        }
        return route.data.key + paramKey.sum;
    }

    public shouldDetach(route: ActivatedRouteSnapshot): boolean {
        console.info("CustomReuseStrategy.shouldDetach() - route key: " + this.calcKey(route));
        return !("product" === this.calcKey(route));
    }


    public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        let storedRoute: RouteStorageObject = {
            snapshot: route,
            handle: handle
        };
        console.info("CustomReuseStrategy.store() - route key: " + this.calcKey(route));
        this.storedRoutes[this.calcKey(route)] = storedRoute;
    }


    public shouldAttach(route: ActivatedRouteSnapshot): boolean {
        console.info("CustomReuseStrategy.shouldAttach() - route key: " + this.calcKey(route));
        return this.storedRoutes[this.calcKey(route)] !== undefined;
    }

    public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        console.info("CustomReuseStrategy.retrieve() - route key: " + this.calcKey(route));
        if (this.storedRoutes[this.calcKey(route)] === undefined) {
            /* Just return undefined */
            return null;
        } else {
            return this.storedRoutes[this.calcKey(route)].handle;
        }
    }


    public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        let returnValue = (future.routeConfig === curr.routeConfig);
        if (future.routeConfig != null && curr.routeConfig != null) {
            returnValue = this.calcKey(future) === this.calcKey(curr);
            console.info("CustomReuseStrategy.shouldReuseRoute() - future: " + this.calcKey(future) + ", curr: " + this.calcKey(curr) +
                ", future.routeConfig.path:" + future.routeConfig.path + ", curr.routeConfig.path:" + curr.routeConfig.path + ", returnValue: " + returnValue);
        } else {
            console.info("CustomReuseStrategy.shouldReuseRoute() - future: " + this.calcKey(future) + ", curr: " + this.calcKey(curr) +
                ", future.routeConfig:" + future.routeConfig + ", curr.routeConfig:" + curr.routeConfig + ", returnValue: " + returnValue);
        }
        return returnValue;
    }
}

In Summary

Following things define in my app and RouteReuseStrategy works fine.

  • Defined routes with data key and children lazy loading
  • Only single route-outlet
  • Unique key for each routes
  • Angular Version 2.4.10 and Router Version 3.4.10

Reference

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!