0

我有一个动态的 BreadCrumb 导航,我需要从 URL 获取参数。为此,我正在执行以下代码:

const userId = this.activatedRoute.params
               .pipe(skipWhile((params: Params) => Number.isNaN(+params['userId'])));

const getAppUserId = userId.pipe(
            switchMap((params: Params) => {
                return +params['userId']
                    ? this.myAppService.getApplicationUser(+params['userId'])
                    : of('')
            }))

但它总是空的,我从来没有将参数传递给 Observable。当我使用queryParams时,它工作正常,但我不想去追求queryParams概念。知道我哪里出错了吗?

4

3 回答 3

0

我曾经做过一个自动面包屑生成器,它只依赖于你的路由中的静态数据。我设法找到了它,所以你去吧,以防它有帮助:

export class RouteBreadcrumbsComponent {

  breadcrumbs = [];

  constructor(
    private router: Router,
  ) {
    let buffer = [];

    /* 
       Listen for router events in reverse order (to get all events).
       From the snapshots, return its path and its breadcrumb.
    */
    this.router.events.pipe(
      filter(event => event instanceof ActivationEnd),
      map((event: ActivationEnd) => [
        event.snapshot.data && event.snapshot.data.crumb || undefined,
        this.determineCorrectPath(event.snapshot),
      ]),
      filter(([crumb, url]) => !!crumb),
    ).subscribe(([crumb, url]) => buffer.push({ crumb, url }));

    this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ).subscribe(event => {
      this.breadcrumbs = buffer.reverse();
      buffer = [];
    });
  }

  determineCorrectPath(snapshot: ActivatedRouteSnapshot) {
    const path = snapshot.routeConfig.path;
    const params = snapshot.params;

    // Path = route with a param, so get the param
    if (path.startsWith(':'))
      return params[path.replace(':', '')];
    // Path = '' = route group or root route of a lazy loaded module, so take the parent path
    else if (!path)
      return snapshot.parent.routeConfig.path;
    // Path can be used as is
    else
      return path;
  }

  buildRoutingArray(crumbIndex: number) {
    return this.breadcrumbs
      .slice(0, crumbIndex + 1)
      .map(crumb => crumb.url)
      .join('/');
  }
}

您所要做的就是为data: { crumb: 'Your component crumb' }您的每条路线提供一个,它应该可以工作。

于 2019-10-02T10:03:24.197 回答
0

首要问题 :

Number.isNaN(+params['userId'])

返回一个字符串,而不是一个数字。

第二题:

const getAppUserId = userId.pipe(
  switchMap((params: Params) => {

您不是从可观察对象中获取参数,而是从用户 ID(实际上是一个布尔值)。

如果您希望“从/通过 observable 获取参数 id,然后将其用于:getAppUserId 和 switchMap 以使用我从 snapshot.params 获得的参数 id 进行 HTTP 调用”

那么正确的代码将是

this.activatedRoute.params.pipe(
  map(params => params.id),
  switchMap(userId => this.myAppService.getApplicationUser(userId)
);

您不应该测试 ID 的有效性:URL 是字符串,您不能信任用户。只需发出请求,如果 ID 不匹配任何内容,那么您的 API 将不会返回任何内容。让 API 对 ID 进行所有控制,而不是您的客户端。

于 2019-10-02T11:18:46.657 回答
0

问题解决了。有点简单...解决方法是从route.snapshot.

this.router.events
        .pipe(filter(event => event instanceof NavigationEnd))
        .pipe(map(() => {return this.activatedRoute;}))
        .pipe(
            map((route) => {
                while (route.firstChild) {route = route.firstChild;}
                return route;
            })
        ).subscribe(route => {
             console.log(`param: ${route.snapshot.params['id']}`);
             ...
             ...
        });
于 2019-10-07T07:31:42.410 回答