Улучшить эту страницуЧто это делает?
Служба $location анализирует URL в адресной строке браузера (на основе window.location) и делает URL доступным для вашего приложения. Изменения в URL адресной строки отражаются в службе $location, а изменения в $location отражаются в адресной строке браузера.
Служба $location:
- Выводит текущий URL в адресной строке браузера, поэтому вы можете:
- Отслеживать и наблюдать за URL.
- Изменять URL.
- Поддерживает синхронизацию между собой и URL браузера, когда пользователь:
- Изменяет адрес в адресной строке браузера.
- Нажимает кнопку «Назад» или «Вперед» в браузере (или нажимает ссылку «История»).
- Нажимает на ссылку на странице.
- Представляет объект URL как набор методов (протокол, хост, порт, путь, поиск, хеш).
Сравнение $location и window.location
| window.location | Служба $location | |
|---|---|---|
| назначение | предоставляет чтение/запись доступа к текущему расположению браузера | то же |
| API | выводит «сырой» объект со свойствами, которые можно напрямую изменять | выводит методы в стиле jQuery для получения и установки значений |
| интеграция с жизненным циклом приложения Angular | нет | знает о всех внутренних фазах жизненного цикла, интегрируется с $watch, ... |
| бесшовная интеграция с API HTML5 | нет | да (с резервным вариантом для устаревших браузеров) |
| осознает docroot/контекст, из которого загружено приложение | нет - window.location.pathname возвращает "/docroot/actual/path" | да - $location.path() возвращает "/actual/path" |
Когда следует использовать $location?
В любое время, когда ваше приложение должно реагировать на изменение текущего URL или если вы хотите изменить текущий URL в браузере.
Что она не делает?
Она не вызывает полную перезагрузку страницы, когда URL браузера изменяется. Чтобы перезагрузить страницу после изменения URL, используйте API более низкого уровня, $window.location.href.
Общий обзор API
Служба $location может вести себя по-разному в зависимости от конфигурации, предоставленной ей при создании. Значения по умолчанию подходят для многих приложений, для других настройка конфигурации может активировать новые функции.
После создания службы $location вы можете взаимодействовать с ней с помощью методов получения и установки значений в стиле jQuery, которые позволяют получить или изменить текущий URL в браузере.
Конфигурация службы $location
Чтобы настроить службу $location , получите $locationProvider и установите параметры следующим образом:
-
html5Mode(mode): {boolean}
true- см. режим HTML5
false- см. режим Hashbang
по умолчанию:false -
hashPrefix(prefix): {string}
префикс, используемый для Hashbang URL (используется в режиме Hashbang или в устаревших браузерах в режиме Html5)
по умолчанию:""
Пример конфигурации
$locationProvider.html5Mode(true).hashPrefix('!');
Методы получения и установки
Служба $location предоставляет методы получения для только для чтения частей URL (absUrl, protocol, host, port) и методы получения/установки для url, path, search, hash:
// get the current path
$location.path();
// change the path
$location.path('/newValue')
Все методы установки возвращают тот же объект $location, чтобы разрешить цепочку вызовов. Например, чтобы изменить несколько сегментов за один раз, используйте цепочку установок так:
$location.path('/newValue').search({key: value});
Метод replace
Существует специальный метод replace, который может быть использован, чтобы сообщить службе $location, что в следующий раз, когда служба $location будет синхронизирована с браузером, последняя запись истории должна быть заменена вместо создания новой. Это полезно, когда вы хотите реализовать переадресацию, которая в противном случае нарушит кнопку «Назад» (переход назад повторно запустит переадресацию). Чтобы изменить текущий URL без создания новой записи истории браузера, вы можете вызвать:
$location.path('/someNewPath');
$location.replace();
// or you can chain these as: $location.path('/someNewPath').replace();
Обратите внимание, что методы установки не обновляют window.location немедленно. Вместо этого, служба $location знает о жизненном цикле scope и объединяет несколько мутаций $location в одну «транзакцию» для объекта window.location во время фазы $digest scope. Поскольку несколько изменений состояния $location будут переданы в браузер как одно изменение, достаточно вызвать метод replace() один раз, чтобы сделать всю «транзакцию» операцией замены вместо добавления в историю браузера. После обновления браузера служба $location сбрасывает флаг, установленный методом replace(), и будущие мутации будут создавать новые записи истории, если метод replace() не будет вызван снова.
Методы установки и кодирование символов
Вы можете передать специальные символы в службу $location , и она закодирует их в соответствии с правилами, указанными в RFC 3986. При обращении к методам:
- Все значения, передаваемые методам установки
$location,path(),search(),hash(), кодируются. - Методы получения (вызовы методов без параметров) возвращают декодированные значения для следующих методов
path(),search(),hash(). - При вызове метода
absUrl(), возвращаемое значение — это полный URL с закодированными сегментами. - При вызове метода
url(), возвращаемое значение — путь, поиск и хеш в формате/path?search=a&b=c#hash. Сегменты также кодируются.
Режимы Hashbang и HTML5
Служба $location имеет два конфигурационных режима, которые управляют форматом URL в адресной строке браузера: режим Hashbang (по умолчанию) и режим HTML5, основанный на использовании API истории HTML5 . Приложения используют один и тот же API в обоих режимах, и служба $location будет работать с соответствующими сегментами URL и API браузера, чтобы обеспечить изменение URL браузера и управление историей.
| Режим Hashbang | Режим HTML5 | |
|---|---|---|
| конфигурация | по умолчанию | { html5Mode: true } |
| формат URL | Hashbang URL во всех браузерах | обычные URL в современных браузерах, Hashbang URL в старых браузерах |
| перезапись ссылок <a href=""> | нет | да |
| требует конфигурации на стороне сервера | нет | да |
Режим Hashbang (режим по умолчанию)
В этом режиме служба $location использует Hashbang URL во всех браузерах. Angular также не перехватывает и не перезаписывает ссылки в этом режиме. То есть ссылки работают как ожидается, а также выполняют полную перезагрузку страницы, когда меняются части URL, отличные от фрагмента хеша.
it('should show example', inject(
function($locationProvider) {
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix('!');
},
function($location) {
// open http://example.com/base/index.html#!/a
$location.absUrl() == 'http://example.com/base/index.html#!/a'
$location.path() == '/a'
$location.path('/foo')
$location.absUrl() == 'http://example.com/base/index.html#!/foo'
$location.search() == {}
$location.search({a: 'b', c: true});
$location.absUrl() == 'http://example.com/base/index.html#!/foo?a=b&c'
$location.path('/new').search('x=y');
$location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
}
));
Режим HTML5
В режиме HTML5 служба $location службы получения и установки значений взаимодействует с URL-адресом браузера через API истории HTML5. Это позволяет использовать обычные сегменты пути и поиска URL вместо их эквивалентов Hashbang. Если API истории HTML5 не поддерживается браузером, служба $location автоматически переключится на использование Hashbang URL. Это освобождает вас от необходимости беспокоиться о том, поддерживает ли браузер, отображающий ваше приложение, API истории или нет; служба $location прозрачно использует лучший доступный вариант.
- Открытие обычного URL в устаревшем браузере —> перенаправление на Hashbang URL
- Открытие Hashbang URL в современном браузере —> переписывание на обычный URL
Обратите внимание, что в этом режиме Angular перехватывает все ссылки (в соответствии с правилами «перезаписи ссылок Html» ниже) и обновляет URL таким образом, что никогда не выполняется полная перезагрузка страницы.
it('should show example', inject(
function($locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
},
function($location) {
// in browser with HTML5 history support:
// open http://example.com/#!/a -> rewrite to http://example.com/a
// (replacing the http://example.com/#!/a history record)
$location.path() == '/a'
$location.path('/foo');
$location.absUrl() == 'http://example.com/foo'
$location.search() == {}
$location.search({a: 'b', c: true});
$location.absUrl() == 'http://example.com/foo?a=b&c'
$location.path('/new').search('x=y');
$location.url() == 'new?x=y'
$location.absUrl() == 'http://example.com/new?x=y'
// in browser without html5 history support:
// open http://example.com/new?x=y -> redirect to http://example.com/#!/new?x=y
// (again replacing the http://example.com/new?x=y history item)
$location.path() == '/new'
$location.search() == {x: 'y'}
$location.path('/foo/bar');
$location.path() == '/foo/bar'
$location.url() == '/foo/bar?x=y'
$location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
}
));
Резервный вариант для устаревших браузеров
Для браузеров, поддерживающих API истории HTML5, служба $location использует API истории HTML5 для записи пути и поиска. Если API истории не поддерживается браузером, служба $location предоставляет Hashbang URL. Это освобождает вас от необходимости беспокоиться о том, поддерживает ли браузер, отображающий ваше приложение, API истории или нет; служба $location делает это прозрачным для вас.
Перезапись ссылок Html
При использовании режима API истории HTML5 вам не понадобятся специальные ссылки Hashbang. Всё, что вам нужно сделать, это указать обычные URL-ссылки, такие как: <a href="/some?foo=bar">link</a>
Когда пользователь нажимает на эту ссылку,
- В устаревшем браузере URL изменяется на
/index.html#!/some?foo=bar. - В современном браузере URL изменяется на
/some?foo=bar.
В таких случаях, как следующие, ссылки не перезаписываются; вместо этого браузер выполнит полную перезагрузку страницы по исходной ссылке.
- Ссылки, содержащие элемент
target,
Пример:<a href="/ext/link?a=b" target="_self">link</a> - Абсолютные ссылки, ведущие на другой домен,
Пример:<a href="http://angularjs.org/">link</a> - Ссылки, начинающиеся с «/», которые ведут к другому базовому пути,
Пример:<a href="/not-my-base/link">link</a>
Серверная сторона
Использование этого режима требует перезаписи URL на стороне сервера, по сути, вам нужно переписать все ваши ссылки на точку входа вашего приложения (например, index.html).
Относительные ссылки
Убедитесь, что все относительные ссылки, изображения, скрипты и т.д. указаны правильно. Вы должны либо указать базовый URL в заголовке вашего основного HTML-файла (<base href="/my-base">), либо использовать абсолютные URL (начинающиеся с /) повсюду, потому что относительные URL будут преобразованы в абсолютные URL с использованием начального абсолютного URL документа, который часто отличается от корня приложения.
Сильно рекомендуется запускать приложения Angular с включенным API истории HTML5 из корня документа, так как это решает все проблемы с относительными ссылками.
Передача ссылок между разными браузерами
Благодаря функциям переписывания в режиме HTML5 ваши пользователи смогут открывать обычные URL-ссылки в устаревших браузерах и ссылки Hashbang в современных браузерах:
- Современные браузеры перепишут URL с хэшбангом на обычные URL.
- Старые браузеры перенаправят обычные URL на URL с хэшбангом.
Здесь вы можете увидеть два $location экземпляра, оба в режиме Html5, но в разных браузерах, чтобы вы могли увидеть различия. Эти $location службы подключены к фальшивым браузерам. Каждый ввод представляет адресную строку браузера.
Обратите внимание, что при вводе URL с хэшбангом в первый браузер (или наоборот) он не переписывается / перенаправляется на обычный / URL с хэшбангом, так как это преобразование происходит только во время анализа начального URL = при перезагрузке страницы.
В этих примерах мы используем <base href="/base/index.html" />
Браузер в режиме HTML5
Браузер в режиме обратной совместимости HTML5 (режим хэшбанг)
Ограничения
Переход при перезагрузке страницы
Служба $location позволяет изменить только URL; она не позволяет перезагрузить страницу. Если вам необходимо изменить URL и перезагрузить страницу или перейти на другую страницу, используйте API более низкого уровня, $window.location.href.
Использование $location вне жизненного цикла области видимости
$location знает о жизненном цикле области видимости Angular scope. Когда в браузере изменяется URL, он обновляет $location и вызывает $apply, чтобы все $watchers / $observers получили уведомление. Когда вы изменяете $location внутри фазы $digest, все в порядке; $location распространит это изменение в браузер и уведомит все $watchers / $observers. Если вы хотите изменить $location извне Angular (например, через событие DOM или во время тестирования), вы должны вызвать $apply для распространения изменений.
$location.path() и префиксы ! или /
Путь всегда должен начинаться с прямой косой черты (/); установщик $location.path() добавит прямую косую черту, если она отсутствует.
Обратите внимание, что префикс ! в режиме хэшбанг не является частью $location.path(); он фактически представляет собой hashPrefix.
Обход вашего приложения
Для индексирования вашего AJAX-приложения необходимо добавить специальный тег мета в секцию head вашего документа:
<meta name="fragment" content="!" />
Это заставит робота-индексатор запросить ссылки с параметром _escaped_fragment_, чтобы ваш сервер мог распознать робота-индексатор и предоставить HTML-снимки. Дополнительную информацию об этой технике можно найти на странице Making AJAX Applications Crawlable.
Тестирование с помощью службы $location
При использовании службы $location во время тестирования вы находитесь вне жизненного цикла области видимости Angular scope. Это означает, что вы несете ответственность за вызов scope.$apply().
describe('serviceUnderTest', function() {
beforeEach(module(function($provide) {
$provide.factory('serviceUnderTest', function($location){
// whatever it does...
});
});
it('should...', inject(function($location, $rootScope, serviceUnderTest) {
$location.path('/new/path');
$rootScope.$apply();
// test whatever the service should do...
}));
});
Миграция из более ранних версий AngularJS
В более ранних версиях Angular $location использовали hashPath или hashSearch для обработки методов path и search. В этой версии служба $location обрабатывает методы path и search, а затем использует полученную информацию для составления URL с хэшбангом (например, http://server.com/#!/path?search=a), при необходимости.
Изменения в вашем коде
| Навигация внутри приложения | Изменить на |
|---|---|
| $location.href = значение $location.hash = значение $location.update(значение) $location.updateHash(значение) | $location.path(путь).search(поиск) |
| $location.hashPath = путь | $location.path(путь) |
| $location.hashSearch = поиск | $location.search(поиск) |
| Навигация вне приложения | Используйте API более низкого уровня |
| $location.href = значение $location.update(значение) | $window.location.href = значение |
| $location[протокол | хост | порт | путь | поиск] | $window.location[протокол | хост | порт | путь | поиск] |
| Чтение доступа | Изменить на |
| $location.hashPath | $location.path() |
| $location.hashSearch | $location.search() |
| $location.href $location.protocol $location.host $location.port $location.hash | $location.absUrl() $location.protocol() $location.host() $location.port() $location.path() + $location.search() |
| $location.path $location.search | $window.location.path $window.location.search |
Двухсторонняя привязка к $location
Компилятор Angular в настоящее время не поддерживает двухстороннюю привязку к методам (см. проблему). Если вам необходима двухсторонняя привязка к объекту $location (с использованием директивы ngModel на поле ввода), вам нужно будет указать дополнительную модельную переменную (например, locationPath) с двумя $watchers, которые передают обновления $location в обоих направлениях. Например:
Связанный API
© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.2.32/docs/guide/$location