我使用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¶m2=value2")
答案 0 :(得分:359)
通过注入ActivatedRoute
的实例,可以订阅各种可观察对象,包括queryParams
和params
可观察对象:
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非常正确地指出,根据官方文档,在这种情况下,组件unsubscribe()
方法中的onDestroy()
是不必要的。这已从我的代码示例中删除。 (参见{{3>}教程我需要取消订阅吗?部分)
答案 1 :(得分:84)
当这样的网址时 http://stackoverflow.com?param1=value
您可以通过以下代码获取param1:
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"];
}
}
答案 2 :(得分:32)
即使问题指定了版本 beta 7 ,这个问题也会出现在Google上针对 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
这样的网址中读取了查询参数 id 。
仍有一些事情需要注意:
params
之类的params['id']
属性始终会返回字符串,并且可以通过在其前面加{{1}将其转换为数字 }}。答案 3 :(得分:26)
我真的很喜欢@ 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
}
答案 4 :(得分:15)
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'];
});
答案 5 :(得分:11)
您好,您可以使用URLSearchParams,您可以阅读更多相关信息here。
导入:
import {URLSearchParams} from "@angular/http";
和功能:
getParam(){
let params = new URLSearchParams(window.location.search);
let someParam = params.get('someParam');
return someParam;
}
注意:并非所有平台都支持它,而且似乎在&#34;实验&#34;状态由角文档
答案 6 :(得分:7)
使用ActivatedRoute在URL中传递时,您可以获取查询参数,如下所述: -
url: - http:/domain.com?test = 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']));
}
}
答案 7 :(得分:7)
首先,我发现使用Angular2的是带有查询字符串的网址为 /path;query=value1
要在您使用的组件中访问它 这是这样,但现在遵循代码块:
constructor(params: RouteParams){
var val = params.get("query");
}
关于加载组件时它将被删除的原因,这不是默认行为。我在一个干净的测试项目中进行了具体检查,没有重定向或更改。它是默认路由还是其他与路由有关的特殊方法?
在https://angular.io/docs/ts/latest/guide/router.html#!#query-parameters
的Angular2教程中阅读有关查询字符串和参数的路由答案 8 :(得分:5)
获取URL参数作为对象。
import { Router } from '@angular/router';
constructor(private router: Router) {
console.log(router.parseUrl(router.url));
}
答案 9 :(得分:2)
如果您只想获取一次查询参数,最好的方法是使用取方法,这样您就不必担心取消订阅了。 这是简单的片段: -
constructor(private route: ActivatedRoute) {
route.snapshot.queryParamMap.take(1).subscribe(params => {
let category = params.get('category')
console.log(category);
})
}
注意:如果您希望将来使用参数值,请移除 take(1)。
答案 10 :(得分:2)
现在是:
this.activatedRoute.queryParams.subscribe((params: Params) => {
console.log(params);
});
答案 11 :(得分:1)
您只需要在构造函数中注入ActivatedRoute,然后通过它访问参数或queryParams
constructor(private route:ActivatedRoute){}
ngOnInit(){
this.route.queryParams.subscribe(params=>{
let username=params['username'];
});
}
在某些情况下,它在NgOnInit中不提供任何信息...可能是由于在初始化参数之前进行了init调用,在这种情况下,您可以通过使用函数debounceTime(1000)要求observable等待一段时间来实现此目的
e.g =>
constructor(private route:ActivatedRoute){}
ngOnInit(){
this.route.queryParams.debounceTime(100).subscribe(params=>{
let username=params['username'];
});
}
debounceTime()仅在经过特定时间间隔后才发出可观察到的值,而不会发出其他信号
答案 12 :(得分:1)
我希望它会帮助别人。
上面的问题指出,页面重定向后需要查询参数值,并且我们可以假设快照值(无法观察的替代值)就足够了。
这里没有人提到official documentation中的snapshot.paramMap.get。
this.route.snapshot.paramMap.get('id')
因此,在发送之前,请将其添加到发送/重定向组件中:
import { Router } from '@angular/router';
然后重定向为任一重定向(记录在here中):
this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);
或简单地:
this.router.navigate(['/heroes', heroId ]);
确保已按照here的说明将其添加到路由模块中:
{ path: 'hero/:id', component: HeroDetailComponent }
最后,在需要使用查询参数的组件中
添加导入(已记录here):
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
注入已激活的路由
(文档还导入了switchMap,并且还注入了Router和HeroService,但是它们仅在可观察的替代条件下才是必需的-在我们这种情况下,当您使用快照替代方法时就不需要它们了:)
constructor(
private route: ActivatedRoute
) {}
并获得所需的值(记录在here中):
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
}
注意:如果将路由模块添加到功能模块(如文档中所示),请确保在APP.MODULE.ts中将路由模块引入IMPORTS中的AppRoutingModule(或其他具有根级应用程序路径的文件)之前: []。否则将找不到其他功能路由(因为它们将在{path:'**',redirectTo:'/ notfound'}之后出现,并且您只会看到未找到的消息)。
答案 13 :(得分:0)
Steve Paul解决方案的变体,我更愿意避免使用不必要的ivars,因此在unsubscribe()
期间不再需要ngOnDestroy
调用,只需使用take(1)
订阅observable即可将在第一个值后自动释放 - 防止内存泄漏
import 'rxjs/add/operator/take';
import {Router, ActivatedRoute} from '@angular/router';
@Component({...})
export class MyComponent implements OnInit {
constructor(private activatedRoute: ActivatedRoute) {
this.activatedRoute.params.take(1).subscribe((params: any) => {
let userId = params['userId'];
console.log(userId);
});
}
}
答案 14 :(得分:0)
如果未在路由中定义参数,则无法从RouterState获取参数,因此在您的示例中,您必须解析查询字符串...
以下是我使用的代码:
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);
&#13;
答案 15 :(得分:0)
如果您的网址类似https://myapp.com/owner/123/show?height=23,请使用
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
字符串中,然后对URL进行角度编码,则得到类似https://myapp.com/owner/123/show%3Fheight%323的内容-上述解决方案将产生错误的结果(queryParams将为空,如果查询参数位于路径末端,则可以将其粘贴到最后一个路径参数)。在这种情况下,请更改导航方式to this
this.router.navigateByUrl(yourUrl);
答案 16 :(得分:0)
我的旧学校解决方案:
Cookie