Какой самый сжатый способ прочитать параметры запроса в AngularJS?

Я хотел бы прочитать значения параметров URL-запроса, используя AngularJS. Я обращаюсь к HTML со следующим URL-адресом:

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

Как и ожидалось, location.search составляет "?target=bob". Для доступа к значению цели я нашел несколько примеров, перечисленных в Интернете, но ни один из них не работает в AngularJS 1.0.0rc10. В частности, все undefined:

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

Кто-нибудь знает, что будет работать? (Я использую $location в качестве параметра для моего контроллера)


Update:

Я разместил решение ниже, но я не вполне доволен этим. Документация в Руководство разработчика: Angular Сервисы: с помощью $location указано следующее о $location:

Когда следует использовать $location?

Каждый раз, когда ваше приложение должно реагировать на изменение текущего URL или если вы хотите изменить текущий URL-адрес в браузере.

В моем сценарии моя страница будет открыта с внешней веб-страницы с параметром запроса, поэтому я не буду реагировать на изменение текущего URL-адреса. Так что, может быть, $location не является правильным инструментом для работы (для уродливых деталей см. Мой ответ ниже). Поэтому я изменил название этого вопроса: "Как читать параметры запроса в AngularJS с помощью $location?" на "Какой самый сжатый способ чтения параметров запроса в AngularJS?". Очевидно, я мог бы просто использовать javascript и регулярное выражение для синтаксического анализа location.search, но переход на этот низкоуровневый уровень для чего-то такого базового действительно оскорбляет мою чувствительность программиста.

Итак: есть ли лучший способ использовать $location, чем я в своем ответе, или есть ли более краткий вариант?

Ответ 1

Вы можете ввести $routeParams (требуется ngRoute) в ваш контроллер. Вот пример из документов:

// 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: вы также можете получить и установить параметры запроса с помощью службы $location (доступной в ng), в частности ее search: $location.search().

$routeParams менее полезны после начальной загрузки контроллера; $location.search() можно вызывать в любое время.

Ответ 2

Хорошо, что вам удалось заставить его работать с режимом html5, но также можно заставить его работать в режиме hashbang.

Вы можете просто использовать:

$location.search().target

чтобы получить доступ к параметру "target".

Для справки, вот рабочий jsFiddle: 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>

Ответ 3

Чтобы дать частичный ответ на мой собственный вопрос, вот рабочий пример для браузеров 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>

Ключом был вызов $locationProvider.html5Mode(true);, как указано выше. Теперь он работает при открытии http://127.0.0.1:8080/test.html?target=bob. Я не доволен тем, что он не будет работать в старых браузерах, но я мог бы использовать этот подход в любом случае.

Альтернативой, которая будет работать со старыми браузерами, было бы отказаться от вызова html5mode(true) и вместо этого использовать следующий адрес с hash + slash:

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

Соответствующая документация находится в Руководство разработчика: Angular Услуги: использование $location (странно, что мой поиск в Google не нашел этого...).

Ответ 4

Это можно сделать двумя способами:

  • Использование $routeParams

Лучшее и рекомендуемое решение - использовать $routeParams в вашем контроллере. Он требует установки модуля 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. Использование $location.search().

Здесь есть оговорка. Он будет работать только в режиме HTML5. По умолчанию он не работает для URL-адреса, который не имеет хеша (#) в нем http://localhost/test?param1=abc&param2=def

Вы можете заставить его работать, добавив #/ в URL. http://localhost/test#/?param1=abc&param2=def

$location.search(), чтобы вернуть объект, например:

{
  param1: 'abc',
  param2: 'def'
}

Ответ 5

$location.search() будет работать только с включенным режимом HTML5 и только при поддержке браузера.

Это будет работать всегда:

$window.location.search

Ответ 6

Просто для летания.

Если ваше приложение загружается из внешних ссылок, то angular не обнаружит это как изменение URL-адреса, поэтому $loaction.search() предоставит вам пустой объект. Чтобы решить эту проблему, вам нужно установить следующие настройки приложения (app.js)

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

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

Ответ 7

вы также можете использовать $location. $$ search.yourparameter

Ответ 8

это может помочь uou

Какой самый сжатый способ чтения параметров запроса в 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

Ответ 9

Просто точность ответа Эллиса Уайтхеда. $locationProvider.html5Mode(true); не будет работать с новой версией angularjs без указания базового URL-адреса приложения с тегом <base href=""> или установки параметра requireBase на false

Из документа:

Если вы настроите $location для использования html5Mode (history.pushState), вам нужно указать базовый URL-адрес приложения с тегом или настроить $locationProvider, чтобы не требовать базовый тег, передав объект определения с requireBase: false для $locationProvider.html5Mode():

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

Ответ 10

Немного поздно, но я думаю, что ваша проблема была в вашем URL. Если вместо

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

у вас был

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

Я уверен, что это сработало бы. Angular действительно придирчив к своему #/