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

时间:2016-02-28 20:49:31

标签: typescript angular

我使用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")

17 个答案:

答案 0 :(得分:359)

通过注入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非常正确地指出,根据官方文档,在这种情况下,组件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

仍有一些事情需要注意:

  1. 访问params之类的params['id']属性始终会返回字符串,并且可以通过在其前面加{{1}将其转换为数字 }}。
  2. 使用observable获取查询参数的原因是它允许重新使用相同的组件实例而不是加载新的组件实例。每次更改查询参数时,都会导致我们订阅的新事件,因此我们可以相应地对更改做出反应。

答案 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'];
});

Official source

答案 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获取参数,因此在您的示例中,您必须解析查询字符串...

以下是我使用的代码:

&#13;
&#13;
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;
&#13;
&#13;

答案 15 :(得分:0)

查询和路径(角度8)

如果您的网址类似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