简体   繁体   English

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

[英]How to get query params from url in Angular 2?

I use angular2.0.0-beta.7.我使用 angular2.0.0-beta.7。 When a component is loaded on a path like /path?query=value1 it is redirected to /path .当组件加载到/path?query=value1之类的/path?query=value1它会被重定向到/path Why were the GET params removed?为什么删除了 GET 参数? How can I preserve the parameters?如何保留参数?

I have an error in the routers.我在路由器中有错误。 If I have a main route like如果我有一条主要路线,例如

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

and my child route like而我的孩子路线就像

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

then I can't get params in TodoListComponent.那么我无法在 TodoListComponent 中获取参数。 I am able to get我能够得到

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

but I want the classic但我想要经典

query params("/my/path?param1=value1&param2=value2")

By injecting an instance of ActivatedRoute one can subscribe to a variety of observables, including a queryParams and a params observable:通过注入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);
      });
  }

}

A NOTE REGARDING UNSUBSCRIBING关于取消订阅的说明

@Reto and @codef0rmer had quite rightly pointed out that, as per the official docs, an unsubscribe() inside the components onDestroy() method is unnecessary in this instance. @Reto 和 @codef0rmer 非常正确地指出,根据官方文档,在这种情况下,组件onDestroy()方法中的unsubscribe()是不必要的。 This has been removed from my code sample.这已从我的代码示例中删除。 (see blue alert box in this tutorial) (请参阅教程中的蓝色警报框)

When a URL is like this http://stackoverflow.com?param1=value当一个 URL 像这样http://stackoverflow.com?param1=value

You can get the param 1 by the following code:您可以通过以下代码获取参数 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"];
    }
}

Even though the question specifies version beta 7 , this question also comes up as top search result on Google for common phrases like angular 2 query parameters .尽管该问题指定了beta 7版本,但该问题也出现在 Google 上常见短语(如angular 2 查询参数)的最热门搜索结果中。 For that reason here's an answer for the newest router (currently in alpha.7 ).出于这个原因,这里是最新路由器的答案(目前在alpha.7 中)。

The way the params are read has changed dramatically.读取参数的方式发生了巨大变化。 First you need to inject dependency called Router in your constructor parameters like:首先,您需要在构造函数参数中注入名为Router依赖项,例如:

constructor(private router: Router) { }

and after that we can subscribe for the query parameters on our ngOnInit method (constructor is okay too, but ngOnInit should be used for testability) like之后我们可以在我们的ngOnInit方法上订阅查询参数(构造函数也可以,但ngOnInit应该用于可测试性),如

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

In this example we read the query param id from URL like example.com?id=41 .在这个例子中,我们从 URL 中读取查询参数id ,例如example.com?id=41

There are still few things to notice:还有几点需要注意:

  1. Accessing property of params like params['id'] always returns a string , and this can be converted to number by prefixing it with + .访问的属性paramsparams['id']总是返回一个字符串,并且这可以用前缀它被转换为数字+
  2. The reason why the query params are fetched with observable is that it allows re-using the same component instance instead of loading a new one.使用 observable 获取查询参数的原因是它允许重复使用相同的组件实例而不是加载新的实例。 Each time query param is changed, it will cause a new event that we have subscribed for and thus we can react on changes accordingly.每次更改查询参数时,都会导致我们订阅的新事件,因此我们可以对更改做出相应的反应。

I really liked @StevePaul's answer but we can do the same without extraneous subscribe/unsubscribe call.我真的很喜欢@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
}

To send query params发送查询参数

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

To receive query params接收查询参数

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

Official source 官方来源

Hi you can use URLSearchParams, you can read more about it here .您好,您可以使用 URLSearchParams,您可以在此处阅读更多相关信息。

import:进口:

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

and function:和功能:

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

Notice : It's not supported by all platforms and seems to be in "EXPERIMENTAL" state by angular docs注意:并非所有平台都支持它,角度文档似乎处于“实验”状态

Get URL param as an object.获取 URL 参数作为对象。

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

First off, what I have found working with Angular2 is that the url with a query string would be /path;query=value1首先,我发现使用 Angular2 时,带有查询字符串的 url 将是/path;query=value1

To access it in a component you use So is this, but now follows a code block:要在您使用的组件中访问它,就是这样,但现在遵循一个代码块:

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

As to why it would be removed when you load the component, that isn't default behavior.至于为什么在加载组件时会删除它,这不是默认行为。 I checked specificly in a clean test project and wasn't redirected or changed.我专门检查了一个干净的测试项目,没有重定向或更改。 Is it a default route or something else that is special about the routing?它是默认路由还是其他路由的特殊之处?

Read about routing with query strings and params in the Angular2 Tutorial at https://angular.io/docs/ts/latest/guide/router.html#!#query-parametershttps://angular.io/docs/ts/latest/guide/router.html#!#query-parameters的 Angular2 教程中阅读有关使用查询字符串和参数进行路由的信息

You can get the query parameters when passed in URL using ActivatedRoute as stated below:-您可以在使用 ActivatedRoute 传入 URL 时获取查询参数,如下所述:-

url:- http:/domain.com?test=abc 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']));
  }

}

now it is:现在它是:

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

If you only want to get query parameter once, the best way is to use take method so you do not need to worry about unsubscription.如果您只想获取一次查询参数,最好的方法是使用take方法,这样您就不必担心取消订阅。 Here is the simple snippet:-这是简单的片段:-

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

Note: Remove take(1) if you want to use parameter values in future.注意:如果以后要使用参数值,删除take(1)

You just need to inject ActivatedRoute in constructor and then just access params or queryParams over it您只需要在构造函数中注入 ActivatedRoute,然后通过它访问 params 或 queryParams

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

In Some cases it doesn't give anything in NgOnInit ...maybe because of init call before initialization of params in this case you can achieve this by asking observable to wait for some time by function debounceTime(1000)在某些情况下,它不会在 NgOnInit 中给出任何内容......也许是因为在初始化参数之前的 init 调用,在这种情况下,您可以通过函数 debounceTime(1000) 要求 observable 等待一段时间来实现这一点

eg=>例如=>

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

debounceTime() Emits a value from source observable only after particular time span passed without another source emission debounceTime() 仅在经过特定时间跨度后才从源 observable 发出值,而没有另一个源发射

I hope it will help someone else.我希望它会帮助别人。

Question above states that query param value is needed after page has been redirected and we can assume that snapshot value (the no-observable alternative) would be sufficient.上面的问题表明页面重定向后需要查询参数值,我们可以假设快照值(不可观察的替代方案)就足够了。

No one here mentioned about snapshot.paramMap.get from the official documentation .这里没有人提到官方文档中的snapshot.paramMap.get 。

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

So before sending it add this in sending/re-directing component:所以在发送之前在发送/重定向组件中添加它:

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

then re-direct as either (documented here ):然后重新定向为( 在此处记录):

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

or simply:或者干脆:

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

Make sure you have added this in your routing module as documented here :确保你有你的路由模块中添加了这个如记录在这里

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

And finally, in your component which needs to use the query param最后,在需要使用查询参数的组件中

  • add imports (documented here ):添加导入(此处记录):

     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 ): (文档还导入了 switchMap 并注入了 Router 和 HeroService - 但它们仅在 observable 替代中需要 - 当您在我们的情况下使用快照替代时不需要它们):

    constructor(
      private route: ActivatedRoute
    ) {}
  • and get the value you need ( documented here ):并获得您需要的价值( 此处记录):

     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: [] .注意:如果您将路由模块添加到功能模块(如文档所示),请确保在 APP.MODULE.ts 中,路由模块在 AppRoutingModule(或其他具有根级应用程序路由的文件)之前出现在 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).否则将无法找到功能路由(因为它们会在 { path: '**', redirectTo: '/not-found' } 之后出现,并且您只会看到未找到的消息)。

A variation on Steve Paul's solution, I prefer to avoid unnecessary ivars, so to remove the need for the unsubscribe() call during ngOnDestroy , just subscribe to the observable with take(1) and it will be automatically released after the first value - preventing memory leaks Steve Paul的解决方案的变体,我更喜欢避免不必要的ivars,所以为了在ngOnDestroy期间删除对unsubscribe()调用的需要,只需使用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);
    });
  }

}

Query and Path (Angular 8)查询和路径(Angular 8)

If you have url like https://myapp.com/owner/123/show?height=23 then use如果您有像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
    // ...
  })

UPDATE更新

In case when you use this.router.navigate([yourUrl]);如果您使用this.router.navigate([yourUrl]); and your query parameters are embedded in yourUrl string then angular encodes a URL and you get something like this https://myapp.com/owner/123/show%3Fheight%323 - and above solution will give wrong result (queryParams will be empty, and query params can be glued to last path param if it is on the path end).并且您的查询参数嵌入在yourUrl字符串中,然后 angular 对 URL 进行编码,您会得到类似https://myapp.com/owner/123/show%3Fheight%323 的内容- 以上解决方案将给出错误的结果(queryParams 将为空, 并且查询参数可以粘贴到最后一个路径参数(如果它在路径末端)。 In this case change the way of navigation to this在这种情况下,将导航方式更改为此

this.router.navigateByUrl(yourUrl);

My old school solution:我的旧学校解决方案:

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
}

You cannot get a parameter from the RouterState if it's not defined in the route, so in your example, you have to parse the querystring...如果路由中未定义参数,则无法从 RouterState 获取参数,因此在您的示例中,您必须解析查询字符串...

Here is the code I used:这是我使用的代码:

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

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

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