有没有更好的方法来获得Angular2中的祖先路线参数?

gaa*_*gaa 12 typescript angular2-routing angular

我需要从不是父母而不是祖母的路线获得参数,它只是在上面的某个地方,沿着通向根的路径.我知道Angular 2中显示的方法:从父组件或通过共享服务获取RouteParams但是我自己进入的情况(至少我认为是这样)使得那些不适合它的那些.所以这就是我得到的:

我有懒惰加载的子模块,需要id从父上下文.情况或多或少看起来像这样的路由配置:

// Parent/outer module routing
const outerRoutes: Routes = [
    {
        path: 'container/:containerId',
        component: ContainerComponent,
        children: [
            { path: 'model', loadChildren: 'app/container/model/model.module#ModelModule' },
            { path: '', component: ContainerDetailsComponent }
        ]
    }
];

// Child/inner module routing
const innerRoutes: Routes = [
    {
        path: '',
        component: ModelComponent,
        children: [
            { path: ':id', component: ModelDetailsComponent },
            { path: '', component: ModelsComponent }
        ]
    }
];
Run Code Online (Sandbox Code Playgroud)

ModelsComponent需要加载Model属于给定的所有实例Container.所以我决定通过.parent接近但是在写完第二部分之后我的牙齿开始受伤了.parent,还有第三个来了:

this.route.parent.parent.parent.params
  .switchMap((params: Params) => this.modelService.getAllBelongingTo(params['containerId']))
  .subscribe(
    (models: Model[]) => this.models = models,
    error => this.raceEvent = null
  );
Run Code Online (Sandbox Code Playgroud)

共享服务在某种程度上是一种选择,但由于子模块是懒惰加载的事实,我将不得不把它放在核心模块中使它非常全局(我不喜欢).

经过一段时间的努力之后,我来到了一段代码,它简单地将所有代码都ActivatedRoute绑定到根,将它们组合起来,查找param并使用它.我不喜欢它,因为在我看来它太复杂,不可读并且从一英里发臭(或者换句话说就像血腥一样),但是有效并且我不必关心嵌套是否变化.我只需确保:containerId在通往root的路径上的某个地方.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { Model } from './model';
import { ModelService } from './model.service';

@Component({
    ...
})
export class ModelsComponent implements OnInit {
    models: Model[];

    constructor(
        private route: ActivatedRoute,
        private modelService: ModelService) { }

    ngOnInit() {
        const paramsArr = this.route.pathFromRoot.map(route => route.params);

        Observable.combineLatest(paramsArr)
            .switchMap(arrOfParams => {
                const params = arrOfParams.find(p => p['containerId'] !== undefined),
                      id = params && params['containerId'];
                return id ? this.modelService.getAllBelongingTo(id) : [];
            })
            .subscribe(
                (models: Model[]) => {
                    // yay! we got sth
                    this.models = models;
                },
                error => {
                    // handle big nono
                }
            );
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来处理描述的情况?

Ben*_*tan 7

一般来说,我认为你的方法确实有意义.

我不知道代码的确切背景,但它确实感觉像是一个想要了解有关父实例数据的子组件,我同意@ Aravind的评论,这可能最好在全球状态管理解决方案中处理,例如redux或ngrx.话虽这么说,如果这就是你需要的全部,我理解你不会想要引入那种复杂程度.

我只会对您的rxchain进行微调,以便更具可读性.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { Model } from './model';
import { ModelService } from './model.service';

@Component({
    ...
})
export class ModelsComponent implements OnInit {
    models: Model[];

    constructor(
        private route: ActivatedRoute,
        private modelService: ModelService) { }

    ngOnInit() {
        const paramsArr = this.route.pathFromRoot;

        Observable.from(paramsArr)
            .map(route => route.params)
            .filter(params => params.containerId)
            .switchMap(containerId => this.modelService.getAllBelongingTo(containerId))
            .subscribe(
                (models: Model[]) => {
                    // yay! we got sth
                    this.models = models;
                },
                error => {
                    // handle big nono
                }
            );
    }
}
Run Code Online (Sandbox Code Playgroud)

但请注意,此实现仅在有一个containerId作为父项的参数时才设置this.models

编辑1:修正了拼写错误