web-dev-qa-db-fra.com

Changer les paramètres de route sans recharger dans angular 2

Je crée un site Web immobilier en utilisant angular 2, Google Maps, etc. et lorsqu'un utilisateur change le centre de la carte, j'effectue une recherche sur l'API en indiquant la position actuelle de la carte ainsi le rayon. Le problème, c’est que je souhaite refléter ces valeurs dans l’URL sans recharger toute la page. Est-ce possible? J'ai trouvé des solutions avec AngularJS 1.x mais rien sur angular 2.

83
Marcos Basualdo

Vous pouvez utiliser location.go(url) qui modifiera fondamentalement votre URL, sans changer le chemin de l'application.

NOTE Cela pourrait avoir un autre effet, comme une redirection vers une route enfant à partir de la route actuelle.

Question connexe qui décrit location.go ne sera pas intime avec Router pour que des changements se produisent.

67
Pankaj Parkar

A partir de RC6, vous pouvez procéder comme suit pour changer d'URL sans changer d'état et ainsi conserver l'historique de votre itinéraire.

import {OnInit} from '@angular/core';

import {Location} from '@angular/common'; 
// If you dont import this angular will import the wrong "Location"

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.replaceState("/some/newstate/");
  }
}
71
tjuzbumz

Utiliser location.go(url) est la solution, mais au lieu de coder en dur l'URL, envisagez de la générer à l'aide de router.createUrlTree().

Étant donné que vous souhaitez effectuer l'appel suivant du routeur: this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute}) mais sans recharger le composant, il peut être réécrit comme suit:

const url = this
        .router
        .createUrlTree([{param: 1}], {relativeTo: this.activatedRoute})
        .toString();

 this.location.go(url);
44
golfadas

J'ai eu beaucoup de mal à faire en sorte que cela fonctionne dans les versions RCx de angular2. Le package Location a été déplacé et l'exécution de location.go () dans constructor () ne fonctionnera pas. Il doit être ngOnInit () ou plus tard dans le cycle de vie. Voici un exemple de code:

import {OnInit} from '@angular/core';
import {Location} from '@angular/common';

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.go( '/example;example_param=917' );
  }
}

Voici les angular ressources sur le sujet: https://angular.io/docs/ts/latest/api/common/index/Location-class.htmlhttps://angular.io/docs/ts/latest/api/common/index/LocationStrategy-class.html

7
Luke Dupin

Pour ceux qui comme moi trouveraient cette question, les éléments suivants pourraient être utiles.

J'ai eu un problème similaire et j'ai d'abord essayé d'utiliser location.go et location.replaceState comme suggéré dans d'autres réponses ici. Cependant, j'ai rencontré des problèmes lorsque j'ai dû accéder à une autre page de l'application car la navigation était relative à l'itinéraire actuel et que l'itinéraire actuel n'était pas mis à jour par location.go ou location.replaceState (le routeur ne sait rien à propos de ce qu'ils font à l'URL)

Il me fallait essentiellement une solution pour ne pas recharger la page/le composant lorsque le paramètre route était modifié, mais DID mettait à jour l'état de la route en interne.

J'ai fini par utiliser des paramètres de requête. Vous pouvez trouver plus d'informations à ce sujet ici: https://angular-2-training-book.rangle.io/handout/routing/query_params.html

Donc, si vous devez faire quelque chose comme enregistrer une commande et obtenir un ID de commande, vous pouvez mettre à jour l'URL de votre page comme indiqué ci-dessous. Mettre à jour un centre et des données connexes sur une carte serait similaire

// let's say we're saving an order. Initally the URL is just blah/orders
save(orderId) {
    // [Here we would call back-end to save the order in the database]

    this.router.navigate(['orders'], { queryParams: { id: orderId } });
    // now the URL is blah/orders?id:1234. We don't reload the orders
    // page or component so get desired behaviour of not seeing any 
    // flickers or resetting the page.
}

et vous en tenez compte dans la méthode ngOnInit comme:

ngOnInit() {
    this.orderId = this.route
        .queryParamMap
        .map(params => params.get('id') || null);
    // orderID is up-to-date with what is saved in database now, or if
    // nothing is saved and hence no id query paramter the orderId variable
    // is simply null.
    // [You can load the order here from its ID if this suits your design]
}

Si vous avez besoin d'aller directement à la page de commande avec une nouvelle commande (non sauvegardée), vous pouvez faire:

this.router.navigate(['orders']);

Ou si vous avez besoin d'aller directement à la page de commande pour une commande existante (enregistrée), vous pouvez faire:

this.router.navigate(['orders'], { queryParams: { id: '1234' } });
7
TornadoAli

J'utilise cette façon de l'obtenir:

const queryParamsObj = {foo: 1, bar: 2, andThis: 'text'};

this.location.replaceState(
  this.router.createUrlTree(
    [this.locationStrategy.path().split('?')[0]], // Get uri
    {queryParams: queryParamsObj} // Pass all parameters inside queryParamsObj
  ).toString()
);

-- MODIFIER --

Je pense que je devrais ajouter quelques informations pour cela.

Si vous utilisez this.location.replaceState(), le routeur de votre application n'est pas mis à jour. Par conséquent, si vous utilisez les informations du routeur ultérieurement, il ne correspond pas à cela dans votre navigateur. Par exemple, si vous utilisez localizeService pour changer de langue, après avoir changé de langue, votre application revienne à la dernière URL où vous vous trouviez avant de la changer avec this.location.replaceState().

Si vous ne voulez pas ce comportement, vous pouvez choisir une méthode différente pour l'URL de mise à jour, par exemple:

this.router.navigate(
  [this.locationStrategy.path().split('?')[0]],
  {queryParams: queryParamsObj}
);

Dans cette option, votre navigateur n'actualise pas non plus, mais votre modification URL est également injectée dans Router de votre application. Ainsi, lorsque vous changez de langue, le problème ne se pose pas comme dans this.location.replaceState().

Bien sûr, vous pouvez choisir la méthode adaptée à vos besoins. Le premier est plus léger parce que vous n'engagez pas plus votre application que de changer URL dans le navigateur.

3
kris_IV

Pour moi, c’était en fait un mélange des deux avec Angular 4.4.5.

L'utilisation de router.navigate continuait à détruire mon URL en ne respectant pas la partie realtiveTo: enabledRoute.

J'ai fini avec:

this._location.go(this._router.createUrlTree([this._router.url], { queryParams: { profile: value.id } }).toString())
2
Patrick P.