如何从Angular 5中的URL获取查询参数?

时间:2017-11-23 12:36:56

标签: angular typescript angular-routing

我正在使用angular 5.0.3,我想用一堆查询参数启动我的应用程序。比如“/ app?param1 = hallo& param2 = 123”。 How get query params from url in angular2?中给出的每个提示都不适合我。

如何获取查询参数的任何想法?

private getQueryParameter(key: string): string {
  const parameters = new URLSearchParams(window.location.search);
  return parameters.get(key);
}

这个私有函数可以帮助我获取参数,但我不认为它是新Angular环境中的正确方法。

[更新:] 我的主应用程序看起来像     @零件({...})     export class AppComponent实现OnInit {

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}

18 个答案:

答案 0 :(得分:141)

在Angular 5中,通过订阅this.route.queryParams来访问查询参数。

示例:" / app?param1 = hallo& param2 = 123"

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    console.log('Called Constructor');
    this.route.queryParams.subscribe(params => {
        this.param1 = params['param1'];
        this.param2 = params['param2'];
    });
}

然而,路径变量由" this.route.snapshot.params"

访问

示例:" / param1 /:param1 / param2 /:param2"

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    this.param1 = this.route.snapshot.params.param1;
    this.param2 = this.route.snapshot.params.param2;
}

答案 1 :(得分:57)

这对我来说是最干净的解决方案

async ngOnInit() {
    this.topo = await this._geoService.getUSTopoJson();
    const projection = d3.geoAlbersUsa().scale(1070).translate([ this._width / 2, this._height / 2 ]);
    const path = d3.geoPath().projection(projection);
    this._svg = d3.select('svg')
      .attr('width', this._width)
      .attr('height', this._height);

    this._svg.append('rect')
      .attr('class', 'background')
      .attr('width', this._width)
      .attr('height', this._height);

    const g = this._svg.append('g');

    g.append('g')
      .attr('class', 'states') // <-- Needed to be 'class' instead of 'id'
      .selectAll('path')
      .data(topojson.feature(this.topo, this.topo.objects.states).features)
      .enter().append('path')
      .attr('d', path);

    g.append('path')
      .datum(topojson.mesh(this.topo, this.topo.objects.states, (a, b) => a !== b ))
      .attr('id', 'state-borders')
      .attr('d', path);
  }

答案 2 :(得分:50)

我知道OP要求使用Angular 5解决方案,但是对于所有偶然发现此问题以寻求更新(6+)Angular版本的人来说。引用Docs,关于ActivatedRoute.queryParams(其他大多数答案都基于):

  

两个较旧的属性仍然可用。他们能力不足   他们的替代产品,不推荐使用,以后可能会弃用   角版本。

     

params —包含必需和可选的Observable   特定于路线的参数。请改用paramMap。

     

queryParams —包含可用查询参数的Observable   所有路线。改用queryParamMap。

根据Docs,获取查询参数的简单方法如下:

ngOnInit() {
    this.param1 = this.route.snapshot.paramMap.get('param1');
    this.param2 = this.route.snapshot.paramMap.get('param2');
}

有关更高级的方式(例如,高级组件的重新使用),请参见this文档一章。

编辑:

正如在下面的评论中正确指出的那样,此答案是错误的-至少对于OP指定的情况。

OP要求获取全局查询参数(/ app?param1 = hallo&param2 = 123);在这种情况下,您应该使用queryParamMap(就像在@ dapperdan1985答案中一样)。

另一方面,

paramMap用于特定于路由的参数(例如/ app /:param1 /:param2,结果为/ app / hallo / 123)。

感谢@JasonRoyle和@daka指出来。

答案 3 :(得分:13)

查询和路径参数(角度8)

对于像https://myapp.com/user/666/read?age=23这样的网址,请使用

import { combineLatest } from 'rxjs';
// ...

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let userId = pathParams.get('userId');    // =666
    let age    = queryParams.get('age');      // =23
    // ...
  })

更新

如果使用this.router.navigate([someUrl]);并将查询参数嵌入someUrl字符串中,然后对URL进行角度编码,则得到类似https://myapp.com/user/666/read%3Fage%323的内容-上述解决方案将产生错误的结果(queryParams将为空,如果路径参数位于路径末端,则可以将其保留为最后一个路径参数)。在这种情况下,请更改导航方式to this

this.router.navigateByUrl(someUrl);

答案 4 :(得分:7)

您还可以使用HttpParams,例如:

  getParamValueQueryString( paramName ) {
    const url = window.location.href;
    let paramValue;
    if (url.includes('?')) {
      const httpParams = new HttpParams({ fromString: url.split('?')[1] });
      paramValue = httpParams.get(paramName);
    }
    return paramValue;
  }

答案 5 :(得分:7)

不幸的是,最干净的解决方案不是最可扩展的解决方案。在最新版本的Angular中,在其他答案中建议您可以使用ActivatedRoute Injectible并特别使用以下快照属性之一轻松获取查询参数:

this.route.snapshot.queryParamMap.get('param')

或subscription属性(在查询字符串将更新的情况下使用,例如,在用户ID中导航):

this.route.queryParamMap.subscribe(params => console.log(params));

我在这里告诉您,这些解决方案存在一个巨大的缺陷,但尚未解决一段时间:https://github.com/angular/angular/issues/12157

总而言之,唯一的防弹解决方案是使用良好的旧香草javascript。在这种情况下,我创建了一个用于URL操作的服务:

import { Injectable } from '@angular/core';
import { IUrl } from './iurl';

@Injectable()
export class UrlService {
    static parseQuery(url: string): IUrl {
        const query = url.slice(url.indexOf('?')+1).split('&').reduce( (acc,query) => {
            const parts = query.split('=');
            acc[parts[0]] = parts[1];
            return acc;
        }, {});

        return {
            a: query['a'],
            b: query['b'],
            c: query['c'],
            d: query['d'],
            e: query['e']
        }
    }
}

答案 6 :(得分:5)

import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    console.log(this.route.snapshot.queryParamMap);
}

<强>更新

import { Router, RouterStateSnapshot } from '@angular/router';

export class LoginComponent {
    constructor(private router: Router) {
        const snapshot: RouterStateSnapshot = router.routerState.snapshot;
        console.log(snapshot);  // <-- hope it helps
    }
}

答案 7 :(得分:5)

它对我的工作:

constructor(private route: ActivatedRoute) {}

ngOnInit()
{
    this.route.queryParams.subscribe(map => map);
    this.route.snapshot.queryParams; 
}

查看更多选项How get query params from url in angular2?

答案 8 :(得分:4)

角度Router提供了方法parseUrl(url: string),该方法将url解析为UrlTree。 UrlTree的属性之一是queryParams。因此,您可以执行以下操作:

this.router.parseUrl(this.router.url).queryParams[key] || '';

答案 9 :(得分:2)

当我在寻找类似的解决方案时偶然发现了这个问题,但我并不需要像完整的应用程序级别路由或更多导入的模块那样的东西。

以下代码非常适合我的使用,不需要额外的模块或导入。

  GetParam(name){
    const results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
    if(!results){
      return 0;
    }
    return results[1] || 0;
  }

  PrintParams() {
    console.log('param1 = ' + this.GetParam('param1'));
    console.log('param2 = ' + this.GetParam('param2'));
  }

http://localhost:4200/?param1=hello&param2=123输出:

param1 = hello
param2 = 123

答案 10 :(得分:2)

简单解决方案

 // in routing file
       {
            path: 'checkout/:cartId/:addressId',
            loadChildren: () => import('./pages/checkout/checkout.module').then(m => m.CheckoutPageModule)
          },

    // in Component file

            import { Router, ActivatedRoute } from '@angular/router';

                 constructor(
                      private _Router: ActivatedRoute
                  ) { }

                  ngOnInit() {
                    this.cartId = this._Router.snapshot.params.cartId;
                    this.addressId = this._Router.snapshot.params.addressId;
                    console.log(this.addressId, "addressId")
                    console.log(this.cartId, "cartId")
                  }

答案 11 :(得分:1)

如果您有一个空的路线对象,那主要是因为您没有在app.component.html中使用路由器插座。

如果没有这个,你将无法获得具有非空子对象的有意义的路径对象,特别是params&amp; queryParams。

尝试在致电<router-outlet><router-outlet>

之前添加 <app-main-component></app-main-component>

在此之前,请确保您已在app-routing&gt;中准备好您的查询参数。导出App组件使用的类Route:

param: '/param/:dynamicParam', path: MyMainComponent

最后一件事,为了获得你的参数,我个人使用this.route.snapshot.params.dynamicParam其中dynamicParam是app-routing组件中使用的名称:)

答案 12 :(得分:0)

以下代码对我有用

constructor(private route: ActivatedRoute) {   }
ngOnInit(): void {
   this.route.queryParams.subscribe(params => {
      console.log(params);
    });
}

答案 13 :(得分:0)

只是偶然发现了一个相同的问题,这里的大多数答案似乎只能解决Angular内部路由,然后解决其中的一些路由参数与请求参数不同的问题。

我想我有一个与Lars原始问题类似的用例。

对我来说,用例是引荐跟踪:

Angular在mycoolpage.com上运行,并具有哈希路由,因此mycoolpage.com重定向到mycoolpage.com/#/。但是,对于引用来说,诸如mycoolpage.com?referrer=foo之类的链接也应该可用。不幸的是,Angular立即剥离了请求参数,直接转到mycoolpage.com/#/

不幸的是,使用空组件+ AuthGuard并获得queryParamsqueryParamMap的任何“技巧”都对我不起作用。他们总是空着。

我的骇人听闻的解决方案最终是在index.html中的一个小脚本中处理此问题,该脚本获得完整的URL,带有请求参数。然后,我通过字符串操作获取请求参数值,并将其设置在window对象上。然后,一个单独的服务处理从窗口对象获取ID的问题。

index.html脚本

const paramIndex = window.location.href.indexOf('referrer=');
if (!window.myRef && paramIndex > 0) {
  let param = window.location.href.substring(paramIndex);
  param = param.split('&')[0];
  param = param.substr(param.indexOf('=')+1);
  window.myRef = param;
}

服务

declare var window: any;

@Injectable()
export class ReferrerService {

  getReferrerId() {
    if (window.myRef) {
      return window.myRef;
    }
    return null;
  }
}

答案 14 :(得分:0)

小心你的路线。 A&#34; redirectTo&#34;将删除任何查询参数。

const appRoutes: Routes [
 {path: "one", component: PageOneComponent},
 {path: "two", component: PageTwoComponent},
 {path: "", redirectTo: "/one", pathMatch: full},
 {path: "**", redirectTo: "/two"}
]

我使用&#34; / main?param1 = a&amp; param2 = b等查询参数调用了我的主要组件,并假设我的查询参数到达&#34; ngOnInit()&#34;重定向转发生效前主要组件中的方法。

但这是错误的。重定向将在之前出现,删除查询参数并在没有查询参数的情况下调用主组件中的ngOnInit()方法。

我将路线的第三行改为

{path: "", component: PageOneComponent},

现在我的查询参数可以在主要组件ngOnInit和PageOneComponent中访问。

答案 15 :(得分:-1)

/*
Example below url with two param (type and name) 
URL : http://localhost:4200/updatePolicy?type=Medicare%20Insurance&name=FutrueInsurance
*/ 
  constructor(private route: ActivatedRoute) {
    //Read url query parameter `enter code here`
  this.route.queryParams.subscribe(params => {
    this.name= params['type'];
    this.type= params['name'];
    alert(this.type);
    alert(this.name);

 });

  }

答案 16 :(得分:-1)

如果您不使用Angular路由器,请尝试querystring。安装

npm install --save querystring

到您的项目。在您的组件中执行以下操作

import * as qs from 'querystring';
...
ngOnInit() {
   const params = qs.parse(window.location.search.substring(1));
   ...
}

substring(1)是必需的,因为如果您有类似'/mypage?foo=bar'的名称,则其键名将为?foo

答案 17 :(得分:-2)

我认为是Angular 8:

ActivatedRoute.params已替换为ActivatedRoute.paramMap ActivatedRoute.queryParams已替换为ActivatedRoute.queryParamMap