当使用子路由和兄弟路由的组合时,Angular2 - CustomResueStrategy会出错:无法读取eval中未定义的属性'_outlets'

时间:2017-10-01 06:57:13

标签: angular angular-ui-router angular-router

我有一个Angular 2应用程序,其中包含多个不同功能/组件的选项卡。其中一个选项卡是“产品”,我可以在其中查看产品列表,并通过在搜索字段中键入名称来搜索产品。因此,我在搜索文本字段中键入文本,匹配的记录将被过滤并显示在页面上。然后,我可以单击产品以查看其详细信息,然后返回主产品选项卡。现在,我不想丢失产品页面上的搜索文本和结果。为了解决这个问题,我查看了CustomReuseStrategy

我的app.routing文件看起来有点像:

const appRoutes: Routes =
    [
        {
            path: '',
            component: MainComponent,
            children: [
                {
                    path: '',
                    canActivate: [CanActivateGuard],
                    children: [
                        { path: 'orders', component: OrderComponent, data: { key: 1} },
                        {
                            path: 'products',
                            canActivate: [FeatureEnabledGuard],
                            component: ProductsComponent,
                            data: { key: 2}
                            children: [
                                { path: '', component: FindProductComponent, data: { key: 3} },
                                { path: ':id', component: ProductDetailsComponent, data: { key: 4} },
                            ]
                        },
                    ]
                }
            ]
        }
    ];

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 ("2" === 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));
        console.log('in shouldayyach from storedoute = ' + this.storedRoutes[this.calcKey(route)]);
        console.log('returned in shouldAttached = ' + (this.storedRoutes[this.calcKey(route)] !== undefined));
        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;
    }
}

现在,在这里点击“产品”标签,进行搜索,然后点击产品查看其详细信息,然后点击其他标签“订单”,我收到错误:

无法在eval中读取未定义的属性'_outlets'

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您希望保持应用程序的状态。这是使用Shared servicesNGRX的经典方案。

他们做了什么? 。所有数据都将存储在一个位置,以便当任何组件更改任何数据时,它将保存并通知或省略已更改的数据,并且数据的观察者将使用更改的数据自行更新。