Какой самый сжатый способ прочитать параметры запроса в 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;
}
- Использование
$location.search()
.
Здесь есть оговорка. Он будет работать только в режиме HTML5. По умолчанию он не работает для URL-адреса, который не имеет хеша (#
) в нем http://localhost/test?param1=abc¶m2=def
Вы можете заставить его работать, добавив #/
в URL. http://localhost/test#/?param1=abc¶m2=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 действительно придирчив к своему #/