web-dev-qa-db-fra.com

Quel est le moyen le plus concis de lire les paramètres de requête dans AngularJS?

J'aimerais lire les valeurs des paramètres de requête d'URL en utilisant AngularJS. J'accède au HTML avec l'URL suivante:

http://127.0.0.1:8080/test.html?target=bob

Comme prévu, location.search est "?target=bob". Pour accéder à la valeur de target , j'ai trouvé divers exemples répertoriés sur le Web, mais aucun d'entre eux ne fonctionne dans AngularJS 1.0.0rc10. En particulier, sont tous undefined:

  • $location.search.target
  • $location.search['target']
  • $location.search()['target']

Quelqu'un sait ce qui va marcher? (J'utilise $location en tant que paramètre de mon contrôleur)


Mise à jour:

J'ai posté une solution ci-dessous, mais je ne suis pas entièrement satisfaite. La documentation de Guide du développeur: Angular Services: à l'aide de $ location indique ce qui suit à propos de $location:

Quand devrais-je utiliser $ location?

Chaque fois que votre application doit réagir à une modification de l'URL actuelle ou si vous souhaitez modifier l'URL actuelle dans le navigateur.

Pour mon scénario, ma page sera ouverte à partir d'une page Web externe avec un paramètre de requête. Par conséquent, je ne "réagis pas à une modification de l'URL actuelle" en tant que telle. Alors peut-être que $location n'est pas le bon outil pour le travail (pour les détails laids, voir ma réponse ci-dessous). J'ai donc changé le titre de cette question de "Comment lire les paramètres de requête dans AngularJS à l'aide de $ location?" à "Quel est le moyen le plus concis de lire les paramètres de requête dans AngularJS?". Évidemment, je pourrais simplement utiliser du javascript et des expressions régulières pour analyser location.search, mais opter pour un niveau aussi bas pour quelque chose d'aussi basique choque vraiment les sensibilités de mon programmeur.

Donc: existe-t-il une meilleure façon d'utiliser $location que dans ma réponse ou existe-t-il une alternative concise?

310
Ellis Whitehead

Vous pouvez injecter $ routeParams (nécessite (ngRoute )) dans votre contrôleur. Voici un exemple tiré de la documentation:

// Given:
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}

EDIT: Vous pouvez également obtenir et définir des paramètres de requête avec le service $ location (disponible dans ng), en particulier sa méthode search: $ location.search ( ) .

$ routeParams sont moins utiles après le chargement initial du contrôleur; $location.search() peut être appelé à tout moment.

197
Andrew Joslin

Bien que vous ayez réussi à le faire fonctionner avec le mode html5, il est également possible de le faire fonctionner en mode hashbang.

Vous pouvez simplement utiliser:

$location.search().target

pour accéder au paramètre de recherche 'cible'.

Pour référence, voici le jsFiddle qui fonctionne: http://web.archive.org/web/20130317065234/http://jsfiddle.net/PHnLb/7/

var myApp = angular.module('myApp', []);

function MyCtrl($scope, $location) {

    $scope.location = $location;
    $scope.$watch('location.search()', function() {
        $scope.target = ($location.search()).target;
    }, true);

    $scope.changeTarget = function(name) {
        $location.search('target', name);
    }
}
<div ng-controller="MyCtrl">

    <a href="#!/test/?target=Bob">Bob</a>
    <a href="#!/test/?target=Paul">Paul</a>
    
    <hr/>    
    URL 'target' param getter: {{target}}<br>
    Full url: {{location.absUrl()}}
    <hr/>
    
    <button ng-click="changeTarget('Pawel')">target=Pawel</button>
    
</div>
188

Pour donner une réponse partielle à ma propre question, voici un exemple de travail pour les navigateurs HTML5:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
  <script>
    angular.module('myApp', [], function($locationProvider) {
      $locationProvider.html5Mode(true);
    });
    function QueryCntl($scope, $location) {
      $scope.target = $location.search()['target'];
    }
  </script>
</head>
<body ng-controller="QueryCntl">

Target: {{target}}<br/>

</body>
</html>

La clé était d'appeler $locationProvider.html5Mode(true); comme ci-dessus. Cela fonctionne maintenant lors de l'ouverture de http://127.0.0.1:8080/test.html?target=bob. Je ne suis pas heureux du fait que cela ne fonctionnera pas avec les anciens navigateurs, mais je pourrais quand même utiliser cette approche.

Une alternative qui fonctionnerait avec les anciens navigateurs serait de supprimer l'appel html5mode(true) et d'utiliser l'adresse suivante avec hash + slash:

http://127.0.0.1:8080/test.html#/?target=bob

La documentation pertinente est à Guide du développeur: Angular Services: Utilisation de $ location (étrange que ma recherche sur Google n'ait pas trouvé cela ...).

56
Ellis Whitehead

Cela peut être fait de deux manières:

  1. Utiliser $routeParams

La meilleure solution recommandée consiste à utiliser $routeParams dans votre contrôleur. Cela nécessite l'installation du module ngRoute.

   function MyController($scope, $routeParams) {
      // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
      // Route: /Chapter/:chapterId/Section/:sectionId
      // $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
      var search = $routeParams.search;
  }
  1. Utiliser $location.search().

Il y a une mise en garde ici. Cela fonctionnera uniquement avec le mode HTML5. Par défaut, cela ne fonctionne pas pour l'URL qui n'a pas de hachage (#) _ http://localhost/test?param1=abc&param2=def

Vous pouvez le faire fonctionner en ajoutant #/ dans l'URL. http://localhost/test#/?param1=abc&param2=def

$location.search() pour retourner un objet tel que:

{
  param1: 'abc',
  param2: 'def'
}
17
Fizer Khan

$ location.search () fonctionnera uniquement avec le mode HTML5 activé et uniquement sur les navigateurs compatibles.

Cela fonctionnera toujours:

$ window.location.search

9
Illidan

Juste pour résumer.

Si votre application est en cours de chargement à partir de liens externes, alors angular ne le détectera pas comme un changement d'URL. Par conséquent, $ loaction.search () vous donnera un objet vide. Pour résoudre ce problème, vous devez définir ce qui suit dans la configuration de votre application (app.js).

.config(['$routeProvider', '$locationProvider', function ($routeProvider,     $locationProvider) 
{
   $routeProvider
      .when('/', {
         templateUrl: 'views/main.html',
         controller: 'MainCtrl'
      })
      .otherwise({
         redirectTo: '/'
      });

      $locationProvider.html5Mode(true);
 }]);
6
sapy

Juste une précision à la réponse d'Ellis Whitehead. $locationProvider.html5Mode(true); ne fonctionnera pas avec la nouvelle version d'angularjs sans spécifier l'URL de base de l'application avec une balise <base href=""> ou sans définir le paramètre requireBase sur false.

de la doc :

Si vous configurez $ location pour utiliser html5Mode (history.pushState), vous devez spécifier l'URL de base de l'application avec une balise ou configurer $ locationProvider pour qu'il ne nécessite pas de balise de base en passant un objet de définition avec requireBase: false à $ locationProvider. html5Mode ():

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});
2
S.Thiongane

vous pouvez également utiliser $ location. $$ search.yourparameter

1
thewindev

J'ai constaté que, pour un SPA HTML5Mode, il y a beaucoup de problèmes d'erreur 404, et il n'est pas nécessaire de faire fonctionner $ location.search dans ce cas. Dans mon cas, je souhaite capturer un paramètre de chaîne de requête d'URL lorsqu'un utilisateur se rend sur mon site, quelle que soit la "page" vers laquelle il est initialement lié, ET pouvoir l'envoyer à cette page une fois qu'il est connecté. ce genre de choses dans app.run

$rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
    if (fromState.name === "") {
        e.preventDefault();
        $rootScope.initialPage = toState.name;
        $rootScope.initialParams = toParams;
        return;
    }
    if ($location.search().hasOwnProperty('role')) {
        $rootScope.roleParameter = $location.search()['role'];
    }
    ...
}

plus tard, après la connexion, je peux dire $ state.go ($ rootScope.initialPage, $ rootScope.initialParams)

1
nuander

cela peut vous aider

Quel est le moyen le plus concis de lire les paramètres de requête dans AngularJS

// Given:
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
  <script>
    angular.module('myApp', [], function($locationProvider) {
      $locationProvider.html5Mode(true);
    });
    function QueryCntl($scope, $location) {
      $scope.target = $location.search()['target'];
    }
  </script>
</head>
<body ng-controller="QueryCntl">

Target: {{target}}<br/>

</body>
</html>

($location.search()).target
1
krishna