170 votes

Angular: Comment mettre à jour queryParams sans changer de route

Je suis en train de mettre à jour (ajout, suppression) queryParams à partir d'un composant. Dans angularJS, il était possible grâce à :

$location.search('f', 'filters[]'); // setter
$location.search()['filters[]'];    // getter

J'ai une application avec une liste que l'utilisateur peut filtrer, de l'ordre, etc et je voudrais mettre dans le queryParams de l'url de tous les filtres activés, de sorte qu'il peut copier/coller l'url ou le partager avec quelqu'un d'autre.

Cependant, je ne veux pas que ma page soit rechargée à chaque fois qu'un filtre est sélectionné.

Est-ce faisable avec le nouveau routeur?

368voto

Vous pouvez accéder à l'itinéraire actuel avec une nouvelle requête params, qui ne sera pas de recharger votre page, mais s'requête de mise à jour params.

Quelque chose comme (dans le composant):

constructor(private router: Router) { }

public myMethodChangingQueryParams() {
  const queryParams: Params = { myParam: 'myNewValue' };

  this.router.navigate(
    [], 
    {
      relativeTo: activatedRoute,
      queryParams: queryParams, 
      queryParamsHandling: "merge", // remove to replace all query params by provided
    });
}

Remarque, alors qu'il ne recharge pas la page, il va pousser une nouvelle entrée à l'historique du navigateur. Si vous voulez la remplacer dans l'histoire au lieu d'ajouter une nouvelle valeur, vous pouvez utiliser { queryParams: queryParams, replaceUrl: true }.

EDIT: Comme l'a déjà souligné dans les commentaires, [] et de la relativeTo propriété manquait dans mon premier exemple, il pourrait avoir changé l'itinéraire ainsi, non seulement la requête params. Le bon this.router.navigate d'utilisation sera dans ce cas:

this.router.navigate(
  [], 
  {
    relativeTo: this.activatedRoute,
    queryParams: { myParam: 'myNewValue' },
    queryParamsHandling: "merge"
  });

La nouvelle valeur du paramètre null va supprimer le paramètre de l'URL.

29voto

Robert Points 598

La réponse de @ Radosław Roszkowiak est presque exacte, sauf que relativeTo: this.route est requis comme ci-dessous:

 constructor(
  private router: Router,
  private route: ActivatedRoute,
) {}

changeQuery() {
  this.router.navigate(['.'], { relativeTo: this.route, queryParams: { ... }});
}
 

19voto

bjornalm Points 109

Dans Angulaire 5, vous pouvez facilement obtenir et de modifier une copie de la urlTree par l'analyse de l'url courante. Cela comprendra la requête params et de fragments.

  let urlTree = this.router.parseUrl(this.router.url);
  urlTree.queryParams['newParamKey'] = 'newValue';

  this.router.navigateByUrl(urlTree); 

La "bonne voie" pour modifier un paramètre de requête est probablement avec l' createUrlTree comme ci-dessous, qui crée une nouvelle UrlTree de l'actuel tout en nous permettant de le modifier à l'aide de NavigationExtras.

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

constructor(private router: Router) { }

appendAQueryParam() {

  const urlTree = this.router.createUrlTree([], {
    queryParams: { newParamKey: 'newValue' },
    queryParamsHandling: "merge",
    preserveFragment: true });

  this.router.navigateByUrl(urlTree); 
}

Pour supprimer un paramètre de requête de cette façon, vous pouvez le configurer pour undefined ou null.

13voto

moi_meme Points 3966

La réponse avec le plus de vote a partiellement fonctionné pour moi. L'URL du navigateur est restée la même, mais mon routerLinkActive ne fonctionnait plus après la navigation.

Ma solution était d'utiliser lotation.go:

 import { Component } from "@angular/core";
import { Location } from "@angular/common";
import { HttpParams } from "@angular/common/http";

export class whateverComponent {
  constructor(private readonly location: Location, private readonly router: Router) {}

  addQueryString() {
    const params = new HttpParams();
    params.append("param1", "value1");
    params.append("param2", "value2");
    this.location.go(this.router.url.split("?")[0], params.toString());
  }
}
 

J'ai utilisé HttpParams pour construire la chaîne de requête car je l'utilisais déjà pour envoyer des informations avec httpClient. mais vous pouvez simplement le construire vous-même.

et this._router.url.split("?")[0] , consiste à supprimer toutes les chaînes de requête précédentes de l'URL actuelle.

8voto

Azeem Chauhan Points 84

Si vous souhaitez modifier les paramètres de requête sans modifier l'itinéraire. Voir l'exemple ci-dessous pourrait vous aider: l'itinéraire actuel est: / search et l'itinéraire cible est (sans recharger la page): / search? query = love

 submit(value: string) {
{ this.router.navigate( ['.'],  { queryParams: { query: value } })
    .then(_ => this.search(q));
}
search(keyword:any) { 
//do some activity using }
 

Veuillez noter que vous pouvez utiliser this.router.navigate (['search'] au lieu de this.router.navigate (['.']

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X