¿Cuál es la forma más concisa de leer los parámetros de consulta en AngularJS?

Me gustaría leer los valores de los parámetros de consulta de la URL utilizando AngularJS. Estoy accediendo al HTML con la siguiente URL:

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

Como era de esperar, location.search es "?target=bob". Para acceder al valor de target, he encontrado varios ejemplos en la web, pero ninguno de ellos funciona en AngularJS 1.0.0rc10. En particular, los siguientes son todos indefinidos:

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

¿Alguien sabe lo que va a trabajar? (Estoy usando $location como parámetro de mi controlador)


Actualizar:

He publicado una solución a continuación, pero no estoy del todo satisfecho con ella. La documentación en Developer Guide: Angular Services: Using $location dice lo siguiente sobre $location:

¿Cuándo debo usar $location?

Siempre que tu aplicación necesite reaccionar a un cambio en la URL o si quieres cambiar la URL actual en el navegador.

Para mi escenario, mi página se abrirá desde una página web externa con un parámetro de consulta, por lo que no estoy "reaccionando a un cambio en la URL actual" per se. Así que tal vez $location no es la herramienta adecuada para el trabajo (para los detalles feos, ver mi respuesta a continuación). Por lo tanto, he cambiado el título de esta pregunta de "¿Cómo leer los parámetros de consulta en AngularJS utilizando $location?" a "¿Cuál'es la forma más concisa de leer los parámetros de consulta en AngularJS?". Obviamente, podría usar javascript y una expresión regular para analizar location.search, pero ir a ese nivel tan bajo para algo tan básico realmente ofende mi sensibilidad de programador.

Así que: ¿hay una mejor manera de usar $location que la que yo hago en mi respuesta, o hay una alternativa concisa?

Puede inyectar $routeParams (requiere ngRoute) en su controlador. Aquí'hay un ejemplo de la documentación:

// 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: También puedes obtener y establecer parámetros de consulta con el servicio $location (disponible en ng), particularmente su método search: $location.search().

Los $routeParams son menos útiles después de la carga inicial del controlador; $location.search() puede ser llamado en cualquier momento.

Comentarios (6)

Que bueno que hayas logrado hacerlo funcionar con el modo html5 pero también es posible hacerlo funcionar en el modo hashbang.

Podrías simplemente utilizar:

$location.search().target

para acceder al parámetro de búsqueda 'objetivo'.

Para la referencia, aquí está el jsFiddle de trabajo: http://web.archive.org/web/20130317065234/http://jsfiddle.net/PHnLb/7/

Comienza el snippet: js hide: false -->

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/>

    target=Pawel

</div>

...fin del fragmento..;

Comentarios (12)

Para dar una respuesta parcial a mi propia pregunta, aquí hay una muestra que funciona para los navegadores HTML5:




  <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>



Target: {{target}}<br/>


La clave fue llamar a $locationProvider.html5Mode(true); como se hizo anteriormente. Ahora funciona al abrir http://127.0.0.1:8080/test.html?target=bob. No estoy contento con el hecho de que no funcione en los navegadores más antiguos, pero podría utilizar este enfoque de todos modos.

Una alternativa que funcionaría con navegadores más antiguos sería eliminar la llamada html5mode(true) y usar la siguiente dirección con hash+barra en su lugar:

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

La documentación relevante está en Developer Guide: Angular Services: Using $location (es extraño que mi búsqueda en google no haya encontrado esto...).

Comentarios (3)