Angular 2:如何在路由出口之外获取路由参数

8
类似于 Angular2 在 router-outlet 以外获取路由参数 的问题,但是此问题针对 Angular 2 的发布版本(即路由器的 3.0.0 版本)。我有一个应用程序,其中包含联系人列表和一个路由器出口,用于显示或编辑所选联系人。我想确保在任何时候选择正确的联系人(包括页面加载时),因此我希望能够在每次路由更改时从路由中读取“id”参数。

我可以通过订阅路由器的事件属性来获取路由事件,但是 Event 对象只给我访问原始 URL 的权限,而不是解析后的版本。我可以使用路由器的 parseUrl 方法解析它,但这种格式并不特别有用,而且相当脆弱,所以我宁愿不使用它。我还查看了路由器的 routerState 属性中的所有路由事件,但快照中的 params 总是一个空对象。

是否有一种实际简单的方法来做到这一点?我需要在一个永远不会更改的 router-outlet 中包装联系人列表才能使其工作吗?或者类似的解决方案?

2个回答

3
如果有人正在寻找这个问题的最新解决方案(针对Angular 8),我发现了这篇文章,对我非常有效。
可以在路由器出口之外的组件中直接进行相同的实现,它仍然可以正常工作。
文章链接:https://medium.com/@eng.ohadb/how-to-get-route-path-parameters-in-an-angular-service-1965afe1470e
    export class MyParamsAwareService {
  constructor(private router: Router) { 
    this.router.events
      .pipe(
        filter(e => (e instanceof ActivationEnd) && (Object.keys(e.snapshot.params).length > 0)),
        map(e => e instanceof ActivationEnd ? e.snapshot.params : {})
      )
      .subscribe(params => {
      console.log(params);
      // Do whatever you want here!!!!
      });
  }

为了避免读者经历我所经历的困难。

0

我一整天都在苦苦挣扎这个问题,但是我终于通过监听路由事件之一找到了解决方法。准备好了吗?这个方法有点棘手(丑陋?),但至少在最新版本的Angular(4.x)和Angular Router(4.x)中可以使用。如果他们改变了什么,这段代码可能在未来无法使用。

基本上,我找到了一种获取路由路径并自己重建自定义参数映射的方法。

所以,这就是它:

import { Component, OnInit } from '@angular/core';
import { Router, RoutesRecognized } from '@angular/router';

@Component({
  selector: 'outside-router-outlet',
  templateUrl: './outside-router-outlet.component.html',
  styleUrls: ['./outside-router-outlet.component.css']
})

export class OutSideRouterOutletComponent implements OnInit {
  path: string;
  routeParams: any = {};

  constructor(private router: Router) { }

  ngOnInit() {
    this.router.events.subscribe(routerEvent => {
      if (routerEvent instanceof RoutesRecognized) {
          this.path = routerEvent.state.root['_routerState']['_root'].children[0].value['_routeConfig'].path;
          this.buildRouteParams(routerEvent);
      }
    });
  } 

  buildRouteParams(routesRecognized: RoutesRecognized) {
    let paramsKey = {};
    let splittedPath = this.path.split('/');
    splittedPath.forEach((value: string, idx: number, arr: Array<string>) => {
      // Checking if the chunk is starting with ':', if yes, we suppose it's a parameter
      if (value.indexOf(':') === 0) {
        // Attributing each parameters at the index where they were found in the path
        paramsKey[idx] = value;
      }
    });
    this.routeParams = {};
    let splittedUrl = routesRecognized.url.split('/');
    /**
     * Removing empty chunks from the url,
     * because we're splitting the string with '/', and the url starts with a '/')
     */
    splittedUrl = splittedUrl.filter(n => n !== "");
    for (let idx in paramsKey) {
      this.routeParams[paramsKey[idx]] = splittedUrl[idx];
    }
    // So here you now have an object with your parameters and their values
    console.log(this.routeParams);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接