简体   繁体   English

Angular 2:如何从路由器插座外部获取路线的参数

[英]Angular 2: How do I get params of a route from outside of a router-outlet

Similar question to Angular2 Get router params outside of router-outlet but targeting the release version of Angular 2 (so version 3.0.0 of the router).Angular2类似的问题Get router params outside of router-outlet但针对 Angular 2 的发布版本(因此版本为 3.0.0 的路由器)。 I have an app with a list of contacts and a router outlet to either display or edit the selected contact.我有一个带有联系人列表和路由器插座的应用程序,可以显示或编辑所选联系人。 I want to make sure the proper contact is selected at any point (including on page load), so I would like to be able to read the "id" param from the route whenever the route is changed.我想确保在任何时候(包括页面加载时)都选择了正确的联系人,因此我希望能够在更改路线时从路线中读取“id”参数。

I can get my hands on routing events by subscribing to the router's events property, but the Event object just gives me access to the raw url, not a parsed version of it.我可以通过订阅路由器的 events 属性来处理路由事件,但是 Event 对象只让我访问原始 url,而不是它的解析版本。 I can parse that using the router's parseUrl method, but the format of this isn't particularly helpful and would be rather brittle, so I'd rather not use it.我可以使用路由器的 parseUrl 方法解析它,但是它的格式并不是特别有用,而且会很脆弱,所以我宁愿不使用它。 I've also looked all though the router's routerState property in the routing events, but params is always an empty object in the snapshot.我还查看了路由事件中路由器的 routerState 属性,但 params 在快照中始终是一个空对象。

Is there an actual straight forward way to do this that I've just missed?有没有一种我刚刚错过的实际直接的方法来做到这一点? Would I have to wrap the contact list in a router-outlet that never changes to get this to work, or something like that?我是否必须将联系人列表包装在永远不会改变的路由器插座中才能使其正常工作,或者类似的东西?

I've been struggling with this issue for the whole day, but I think I finally figured out a way on how to do this by listening to one of the router event in particular.我一整天都在为这个问题苦苦挣扎,但我想我终于找到了一种方法,特别是通过监听一个路由器事件来做到这一点。 Be prepared, it's a little bit tricky (ugly ?), but as of today it's working, at least with the latest version of Angular (4.x) and Angular Router (4.x).做好准备,这有点棘手(丑陋?),但截至今天,它正在运行,至少在最新版本的 Angular (4.x) 和 Angular Router (4.x) 上是有效的。 This piece of code might not be working in the future if they change something.如果他们更改某些内容,这段代码将来可能无法工作。

Basically, I found a way to get the path of the route, and then to rebuild a custom parameters map by myself.基本上,我找到了一种获取路由路径的方法,然后自己重​​建自定义参数图。

So here it is:所以这里是:

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);
  }
}

If any body was looking for the latest solution of this issue (angular 8) I stumbled upon this article which worked very well for me.如果有人正在寻找这个问题的最新解决方案(角度 8),我偶然发现了这篇对我来说非常有效的文章。

https://medium.com/@eng.ohadb/how-to-get-route-path-parameters-in-an-angular-service-1965afe1470e https://medium.com/@eng.ohadb/how-to-get-route-path-parameters-in-an-angular-service-1965afe1470e

Obviously you can do the same implementation straight in a component outside the router outlet and it should still work.显然,您可以直接在路由器插座外的组件中执行相同的实现,它应该仍然有效。

    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!!!!
      });
  }

In the hope to spare the same struggle I went through.为了避免我经历的同样的斗争。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM