web-dev-qa-db-fra.com

Définissez les paramètres de requête d'URL sans changement d'état à l'aide de Angular ui-router

Comment dois-je mettre à jour l'URL de la barre d'adresse avec un paramètre de requête changeant en utilisant le routeur ui d'AngularJS pour conserver l'état lors de l'actualisation de la page?

Actuellement, j'utilise $state.transitionTo('search', {q: 'updated search term'}) chaque fois que l'entrée est modifiée, mais le problème est que cela recharge le contrôleur, redessine la fenêtre et perd le focus de saisie de texte.

Est-il possible de mettre à jour stateParams et de le synchroniser avec l'URL de la fenêtre?

65
Petrus Theron

J'avais des problèmes avec .transitionTo jusqu'à ce que je mette à jour à i-router 0.2.14. 0.2.14 change correctement la barre d’emplacement (sans recharger le contrôleur) en utilisant un appel comme celui-ci:

$state.transitionTo('search', {q: 'updated search term'}, { notify: false });
78
pmont

edit: Joué avec cela un peu plus aujourd'hui, et s'est rendu compte que angular ui-router a une option similaire au routeurProvider natif: "reloadOnSearch".

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#options-1

Il est défini sur true par défaut, mais si vous le définissez sur false sur votre état, le changement d'état ne se produira pas lorsque les paramètres de la requête seront modifiés. Vous pouvez alors appeler $location.search(params); ou $location.search('param', value); et l'URL changera, mais ui-router ne reconstruira pas la totalité du contrôleur/de la vue. Vous aurez probablement aussi besoin d'écouter le $locationChangeStart événement sur l'étendue racine pour gérer les actions d'historique en arrière dans votre application, car elles ne provoqueront pas non plus de changement d'état.

J'écoute aussi pour le $stateChangeSuccess événement sur la portée de mon contrôleur pour capturer le chargement initial de la page/route.

Il y a des discussions sur github pour utiliser cette fonctionnalité avec des changements de chemin (pas seulement des changements d'URL): https://github.com/angular-ui/ui-router/issues/125 mais je n'ai pas Cela n’a pas été testé car mon cas d’utilisation était spécifique aux paramètres de chaîne de requête.

La version précédente de ma réponse mentionnait ce problème de github:

https://github.com/angular-ui/ui-router/issues/562

Mais il s’agit d’une question légèrement distincte, qui montre spécifiquement la modalité d’un État par rapport à un autre État sans changement d’état non modal. J'ai essayé le correctif dans ce problème, mais il est clair qu'il ne vise pas à empêcher tout l'état de recharger lors du changement d'URL.

28
Jay Klehr

Mis à jour le 19 mai 2015

À partir de ui-router 0.2.15, le problème du rechargement de l'état lors de la modification des paramètres de requête a été résolu. Cependant, la nouvelle mise à jour a cassé les capacités de retour et de transmission de l'historique de l'API d'historique avec des paramètres de requête. Je n'ai pas été capable de trouver une solution de contournement pour cela.

Original

La réponse de Jay n'a pas fonctionné pour moi, pas plus qu'une tonne d'autres réponses. Essayer d'écouter $locationChangeStart Posait des problèmes lorsque j'essayais d'aller et venir dans l'historique du navigateur, car cela me faisait exécuter du code deux fois: une fois lorsque le nouvel état avait changé et un autre parce que $loationChangeStart Avait été déclenché.

J'ai essayé d'utiliser reloadOnSearch=false, Mais cela changements d'état empêchés même lorsque le chemin de l'URL était modifié. J'ai donc finalement réussi à le faire fonctionner comme suit:

Lorsque vous modifiez $location.search() pour mettre à jour les paramètres de la requête, utilisez un "hack" pour désactiver temporairement le rechargement à la recherche, définissez les paramètres de la requête, puis réactivez le rechargement.

$state.current.reloadOnSearch = false;

$location.search('query', [1,2]);

$timeout(function () {
  $state.current.reloadOnSearch = undefined;
});

Cela garantira que les modifications des paramètres de requête ne rechargent pas l'état et que les modifications du chemin d'accès à l'URL rechargeront correctement l'état.

Cependant, l'historique des navigateurs n'a pas été modifié (cela est nécessaire pour savoir quand un paramètre de requête change pour relire l'URL) lorsqu'un paramètre de requête faisait partie de l'URL. J'ai donc également dû ajouter le nom de chaque paramètre de requête à la propriété url de état .

$locationProvider.html5Mode(true);

$stateProvider
  .state('home', {
    url: '/?param1&param2&param3',
    templateUrl: 'home.html',
    controller: 'homeCtrl as home',
  });

Tous les noms de paramètres figurant dans l'URL sont facultatifs lorsqu'ils sont répertoriés de cette façon, mais toute modification apportée à ces noms de paramètres rechargera l'état lorsque vous appuierez sur les boutons Précédent et Suivant du navigateur.

Espérons que d’autres trouveront cela utile et que cela ne leur prendra pas plusieurs jours pour comprendre comment le faire (comme je l’ai fait).

27
Steven Lambert