在Angular 2中如何从url中获取查询参数?

我使用angular2.0.0-beta.7。当一个组件在/path?query=value1这样的路径上加载时,它会被重定向到/path。为什么GET参数被移除?如何保存参数?

我的路由器出错了。如果我有一条主干道

@RouteConfig([
{
path: '/todos/...',
name: 'TodoMain',
component: TodoMainComponent
}
])

我的孩子就像

@RouteConfig([
{ path: '/', component: TodoListComponent, name: 'TodoList', useAsDefault:true },
{ path: '/:id', component: TodoDetailComponent, name:'TodoDetail' }
])

那么我就不能在TodoListComponent中获得参数。我所能得到的

params("/my/path;param1=value1;param2=value2")

但我想要经典的

query params("/my/path?param1=value1&param2=value2")
403658 次浏览

首先,我在使用Angular2时发现带有查询字符串的url应该是/path;query=value1

在您使用的组件中访问它

constructor(params: RouteParams){
var val = params.get("query");
}

至于为什么它会在加载组件时被删除,这不是默认行为。我在一个干净的测试项目中特别检查,没有被重定向或更改。它是默认路由还是其他关于路由的特殊的东西?

在Angular2教程https://angular.io/docs/ts/latest/guide/router.html !#查询参数中阅读关于使用查询字符串和参数进行路由的内容

即使问题指定的版本是β7,这个问题也会出现在谷歌上常见短语如Angular 2查询参数的搜索结果的顶部。因此,这里有一个关于最新路由器的答案(目前在alpha.7中)。

读取参数的方式发生了巨大的变化。首先,你需要在构造函数参数中注入名为Router的依赖项,如下所示:

constructor(private router: Router) { }

之后,我们可以订阅ngOnInit方法上的查询参数(构造函数也可以,但为了可测试性,应该使用ngOnInit)

this.router
.routerState
.queryParams
.subscribe(params => {
this.selectedId = +params['id'];
});

在这个例子中,我们从类似example.com?id=41的URL中读取查询参数id

仍然有一些事情需要注意:

  1. params['id']这样访问params的属性总是返回字符串,并且可以通过添加+前缀将其转换为数量
  2. 使用可观察对象获取查询参数的原因是,它允许重用相同的组件实例,而不是加载一个新的组件实例。每次查询参数被更改时,它都会引起一个我们已经订阅的新事件,因此我们可以对更改做出相应的反应。

通过注入ActivatedRoute的实例,可以订阅各种可观察对象,包括queryParamsparams可观察对象:

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


@Component({...})
export class MyComponent implements OnInit {


constructor(private activatedRoute: ActivatedRoute) {}


ngOnInit() {
// Note: Below 'queryParams' can be replaced with 'params' depending on your requirements
this.activatedRoute.queryParams.subscribe(params => {
const userId = params['userId'];
console.log(userId);
});
}


}

关于取消订阅的说明

@Reto和@codef0rmer已经非常正确地指出,根据官方文档,组件onDestroy()方法中的unsubscribe()在这种情况下是不必要的。这已从我的代码示例中删除。(参见教程中的蓝色警告框)

如果RouterState没有在路由中定义,你就不能从RouterState中获得参数,所以在你的例子中,你必须解析这个querystring…

下面是我使用的代码:

let re = /[?&]([^=#&]+)=([^&#]*)/g;
let match;
let isMatch = true;
let matches = [];
while (isMatch) {
match = re.exec(window.location.href);
if (match !== null) {
matches[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
if (match.index === re.lastIndex) {
re.lastIndex++;
}
}
else {
isMatch = false;
}
}
console.log(matches);

您可以在URL中使用ActivatedRoute时获得查询参数,如下所示

url: http: / domain.com ?测试= abc

import { Component } from '@angular/core';
import { ActivatedRoute }     from '@angular/router';


@Component({
selector: 'my-home'
})
export class HomeComponent {


constructor(private sharedServices : SharedService,private route: ActivatedRoute) {
route.queryParams.subscribe(
data => console.log('queryParams', data['test']));
}


}

嗨,你可以使用URLSearchParams,你可以阅读更多关于它在这里

进口:

import {URLSearchParams} from "@angular/http";

和功能:

getParam(){
let params = new URLSearchParams(window.location.search);
let someParam = params.get('someParam');
return someParam;
}

请注意:并非所有平台都支持它,angular文档似乎还处于“实验性”状态

获取URL参数作为对象。

import { Router } from '@angular/router';
constructor(private router: Router) {
console.log(router.parseUrl(router.url));
}

我真的很喜欢@StevePaul的回答,但我们也可以这样做,没有额外的订阅/退订调用。

import { ActivatedRoute } from '@angular/router';
constructor(private activatedRoute: ActivatedRoute) {
let params: any = this.activatedRoute.snapshot.params;
console.log(params.id);
// or shortcut Type Casting
// (<any> this.activatedRoute.snapshot.params).id
}

当URL是这样 http://stackoverflow.com?param1=value < / p >

你可以通过下面的代码得到参数1:

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


@Component({
selector: '',
templateUrl: './abc.html',
styleUrls: ['./abc.less']
})
export class AbcComponent implements OnInit {
constructor(private route: ActivatedRoute) { }


ngOnInit() {
// get param
let param1 = this.route.snapshot.queryParams["param1"];
}
}

发送查询参数

import { Router } from '@angular/router';
this.router.navigate([ '/your-route' ], { queryParams: { key: va1, keyN: valN } });

接收查询参数

import { ActivatedRoute } from '@angular/router';
this.activatedRoute.queryParams.subscribe(params => {
let value_1 = params['key'];
let value_N = params['keyN'];
});

< a href = " https://angular.io/docs/ts/latest/guide/router.html !#query-parameters" rel="noreferrer">官方来源

如果你只想获得查询参数一次,最好的方法是使用方法,这样你就不需要担心取消订阅。 下面是简单的片段:-

constructor(private route: ActivatedRoute) {
route.snapshot.queryParamMap.take(1).subscribe(params => {
let category = params.get('category')
console.log(category);
})
}

注意:如果你想在将来使用参数值,移除(1)

现在是:

this.activatedRoute.queryParams.subscribe((params: Params) => {
console.log(params);
});

你只需要在构造函数中注入ActivatedRoute,然后在它上面访问params或queryParams

constructor(private route:ActivatedRoute){}
ngOnInit(){
this.route.queryParams.subscribe(params=>{
let username=params['username'];
});
}

在某些情况下,它在NgOnInit中不给出任何东西…可能是因为在初始化参数之前调用了init,在这种情况下,你可以通过函数debounceTime(1000)让可观察对象等待一段时间来实现这一点

如= >

 constructor(private route:ActivatedRoute){}
ngOnInit(){
this.route.queryParams.debounceTime(100).subscribe(params=>{
let username=params['username'];
});
}

debounceTime()仅在特定的时间跨度过去而没有另一个源发射后,才从源可观察对象发出一个值

我希望它能帮助到其他人。

上面的问题指出,在页面被重定向后,查询参数值是需要的,我们可以假设快照值(不可观察的替代方案)就足够了。

这里没有人提到snapshot. parmmap .get来自官方文档

this.route.snapshot.paramMap.get('id')

所以在发送之前,在发送/重定向组件中添加这个:

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

然后重定向为(文档在这里):

this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);

或者仅仅是:

this.router.navigate(['/heroes', heroId ]);

确保你已经在你的路由模块中添加了这个在这里:

 { path: 'hero/:id', component: HeroDetailComponent }

最后,在需要使用查询参数的组件中

  • add imports (documented 在这里):

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

( documentation also imports switchMap and also injects Router and HeroService - but they are needed for observable alternative only - they are NOT needed when you use snapshot alternative as in our case ):

    constructor(
private route: ActivatedRoute
) {}
  • 并获得所需的值(documented 在这里):

    ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    }
    

NOTE: IF YOU ADD ROUTING-MODULE TO A FEATURE MODULE (AS SHOWN IN DOCUMENTATION) MAKE SURE THAT IN APP.MODULE.ts THAT ROUTING MODULE COMES BEFORE AppRoutingModule (or other file with root-level app routes) IN IMPORTS: [] . OTHERWISE FEATURE ROUTES WILL NOT BE FOUND (AS THEY WOULD COME AFTER { path: '**', redirectTo: '/not-found' } and you would see only not-found message).

查询和路径(Angular 8)

如果你有像https://myapp.com/owner/123/show?height=23这样的url,那么使用

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
.subscribe( ([pathParams, queryParams]) => {
let ownerId = pathParams.get('ownerId');    // =123
let height  = queryParams.get('height');    // =height
// ...
})

更新

如果你使用this.router.navigate([yourUrl]);,而你的查询参数被嵌入到yourUrl字符串中,那么angular会对URL进行编码,你会得到类似https://myapp.com/owner/123/show%3Fheight%323的东西——以上解决方案将会给出错误的结果(queryParams将为空,如果它在路径端,查询参数可以粘在last path param上)。在这种情况下,改变导航方式这个

this.router.navigateByUrl(yourUrl);

我的老办法是:

queryParams(): Map<String, String> {
var pairs = location.search.replace("?", "").split("&")
var params = new Map<String, String>()
pairs.map(x => {
var pair = x.split("=")
if (pair.length == 2) {
params.set(pair[0], pair[1])
}
})


return params
}