web-dev-qa-db-fra.com

Comment obtenir les paramètres de requête à partir de l'URL dans Angular 2?

J'utilise angular2.0.0-beta.7. Lorsqu'un composant est chargé sur un chemin tel que /path?query=value1, il est redirigé vers /path. Pourquoi les paramètres GET ont-ils été supprimés? Comment puis-je conserver les paramètres?

J'ai une erreur dans les routeurs. Si j'ai un itinéraire principal comme

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

et mon parcours enfant comme

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

alors je ne peux pas obtenir de paramètres dans TodoListComponent. Je suis capable d'obtenir

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

mais je veux le classique

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

En injectant une instance de ActivatedRoute, on peut souscrire à une variété d'observables, notamment une queryParams et une params observable:

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

}

NOTE CONCERNANT LA DESINSCRIPTION

@Reto et @ codef0rmer avaient à juste titre souligné que, conformément à la documentation officielle, une méthode unsubscribe() à l'intérieur des composants onDestroy() n'est pas nécessaire dans ce cas. Cela a été supprimé de mon exemple de code. (voir la zone d'alerte bleue dans this tutoriel)

379
Stephen Paul

Quand une URL comme celle-ci http://stackoverflow.com?param1=value

Vous pouvez obtenir le param1 par code suivre:

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"];
    }
}
88
Trung

Même si la question spécifie la version beta 7, cette question apparaît également en tant que résultat de recherche optimal sur Google pour des expressions courantes telles que paramètres de requête angulaires 2. Pour cette raison, voici une réponse pour le dernier routeur (actuellement alpha.7).

La façon dont les paramètres sont lus a radicalement changé. Vous devez d’abord injecter une dépendance appelée Router dans vos paramètres de constructeur, comme:

constructor(private router: Router) { }

et après cela, nous pouvons souscrire aux paramètres de requête sur notre méthode ngOnInit (le constructeur convient également, mais ngOnInit devrait être utilisé pour la testabilité) comme

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

Dans cet exemple, nous lisons le paramètre de requête id à partir d'une URL telle que example.com?id=41.

Il y a encore peu de choses à noter:

  1. L'accès à la propriété de params comme params['id'] renvoie toujours un chaîne, qui peut être converti en nombre en le préfixant avec +.
  2. La raison pour laquelle les paramètres de requête sont extraits avec observable est qu’elle permet de réutiliser la même instance de composant au lieu de charger une nouvelle instance. Chaque fois que le paramètre de requête est modifié, un nouvel événement auquel nous sommes abonnés sera créé et nous pourrons ainsi réagir aux modifications en conséquence.
35
Roope Hakulinen

J'ai bien aimé la réponse de @ StevePaul, mais nous pouvons faire la même chose sans appel supplémentaire inscrit/désabonné.

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
}
27
codef0rmer

Pour envoyer des paramètres de requête

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

Pour recevoir des paramètres de requête

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

source officielle

18
dddenis

Salut, vous pouvez utiliser URLSearchParams, vous pouvez en lire plus ici .

importation:

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

et fonction:

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

Remarque : il n'est pas pris en charge par toutes les plateformes et semble être dans l'état "EXPERIMENTAL" de angular docs.

11
Asaf Hananel

Tout d'abord, ce que j'ai trouvé en travaillant avec Angular2, c'est que l'URL avec une chaîne de requête serait /path;query=value1

Pour y accéder dans un composant que vous utilisez So is this, mais qui suit maintenant un bloc de code:

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

Quant à savoir pourquoi il serait supprimé lors du chargement du composant, il ne s’agit pas d’un comportement par défaut. J'ai vérifié spécifiquement dans un projet de test propre et n'a pas été redirigé ou modifié. Est-ce une route par défaut ou quelque chose d'autre qui est spécial sur le routage?

Lisez à propos du routage avec les chaînes de requête et les paramètres dans le didacticiel Angular2 à l’adresse https://angular.io/docs/ts/latest/guide/router.html#!#query-parameters

7
Namirna

Vous pouvez obtenir les paramètres de requête lorsqu'ils sont passés dans une URL à l'aide de ActivatedRoute, comme indiqué ci-dessous: -

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
Saurabh

Récupère l'URL en tant qu'objet.

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

c'est maintenant:

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

Si vous voulez seulement obtenir le paramètre de requête une fois, le meilleur moyen est d'utiliser la méthode take afin que vous n'ayez pas à vous soucier de la désinscription. Voici l'extrait simple: -

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

Remarque: Supprimez take (1) si vous souhaitez utiliser les valeurs de paramètre à l'avenir.

2
Abhishek Chandel

Vous devez juste injecter ActivatedRoute dans le constructeur et ensuite accéder aux paramètres ou à queryParams dessus

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

Dans certains cas, cela ne donne rien dans NgOnInit ... peut-être à cause d'un appel init avant l'initialisation des paramètres. Dans ce cas, vous pouvez y parvenir en demandant à observable d'attendre quelque temps avec la fonction debounceTime (1000).

par exemple =>

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

debounceTime () N'émet une valeur de la source observable qu'après un laps de temps donné sans autre émission source

1
Rajiv

J'espère que cela aidera quelqu'un d'autre.

La question ci-dessus indique que la valeur de paramètre de requête est nécessaire après que la page ait été redirigée et nous pouvons supposer que la valeur de capture instantanée (la variante non observable) serait suffisante.

Personne ici n’a mentionné snapshot.paramMap.get tiré du documentation officielle .

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

Donc, avant de l'envoyer, ajoutez ceci dans le composant d'envoi/redirection:

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

puis redirigez comme suit (documenté ici ):

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

ou simplement:

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

Assurez-vous que vous avez ajouté ceci dans votre module de routage comme documenté ici :

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

Et enfin, dans votre composant qui doit utiliser le paramètre de requête

  • ajouter des importations (documenté ici ):

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

(la documentation importe également switchMap et injecte également Router et HeroService - mais ils ne sont nécessaires que pour une alternative observable - ils ne sont PAS nécessaires lorsque vous utilisez une alternative à l'instantané, comme dans notre cas):

    constructor(
      private route: ActivatedRoute
    ) {}
  • et obtenez la valeur dont vous avez besoin (documenté ici ):

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

REMARQUE: SI VOUS AJOUTEZ UN MODULE DE ROUTAGE À UN MODULE DE CARACTÉRISTIQUE (INDIQUÉ DANS LA DOCUMENTATION), ASSUREZ-VOUS QUE, DANS APP.MODULE.ts, CE MODULE DE ROUTAGE ARRIVE AVANT AppRoutingModule (ou un autre fichier contenant des itinéraires d'application de niveau racine) IMPORTS: []. AUTREMENT, LES ITINÉRAIRES DE FONCTIONNALITÉ NE SERONT PAS TROUVÉS (S'ils arriveraient après {chemin: '**', redirectTo: '/ not-found'} et vous ne verrez que le message non trouvé).

1
Ula

Vous ne pouvez pas obtenir un paramètre de RouterState s'il n'est pas défini dans la route. Dans votre exemple, vous devez analyser la chaîne de requête ...

Voici le code que j'ai utilisé:

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);
0
Julien Ricard

Une variante de la solution de Steve Paul, je préfère éviter les ivars inutiles, afin de supprimer le besoin de l'appel unsubscribe() pendant ngOnDestroy, abonnez-vous simplement à l'observable avec take(1) et il sera automatiquement publié après la première valeur - prévention des fuites de mémoire

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

}
0
ccwasden