Spec-Zone.ru › Angular.js 1.3

Улучшить эту документациюЧто она делает?

Сервис $location парсит URL в адресной строке браузера (на основе window.location) и делает URL доступным вашему приложению. Изменения в URL адресной строки отражаются в сервисе $location, а изменения в $location отражаются в адресной строке браузера.

Сервис $location:

  • Предоставляет доступ к текущему URL в адресной строке браузера, позволяя вам
    • Наблюдать за URL.
    • Изменять URL.
  • Обеспечивает синхронизацию между собой и URL браузера, когда пользователь
    • Изменяет адрес в адресной строке браузера.
    • Нажимает кнопку "Назад" или "Вперед" в браузере (или нажимает ссылку истории).
    • Нажимает на ссылку на странице.
  • Представляет объект URL как набор методов (протокол, хост, порт, путь, поиск, хэштег).

Сравнение $location с window.location

window.location Сервис $location
назначение предоставляет чтение/запись текущего местоположения браузера то же самое
API экспонирует "сырой" объект с свойствами, которые можно напрямую изменить экспонирует методы в стиле jQuery для получения и установки значений
интеграция с жизненным циклом приложения Angular нет знает все внутренние фазы жизненного цикла, интегрируется с $watch, ...
бесшовное интегрирование с HTML5 API нет да (с резервным вариантом для устаревших браузеров)
осознает корневой каталог/контекст, из которого загружается приложение нет - 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|Object}
    true или enabled:true - см. режим HTML5
    false или enabled:false - см. режим с хэштегами
    requireBase:true - см. относительные ссылки
    по умолчанию: enabled:false

  • hashPrefix(prefix): {string}
    префикс, используемый для URL с хэштегами (используется в режиме с хэштегами или в устаревших браузерах в режиме 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, что при следующей синхронизации с браузером последняя запись истории должна быть заменена, а не создана новая. Это полезно при реализации переадресации, которая в противном случае нарушит кнопку "Назад" (переход назад перезапустит переадресацию). Чтобы изменить текущий 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. Сегменты также закодированы.

Режимы с хэштегами и HTML5

Сервис $location имеет два режима конфигурации, которые контролируют формат URL в адресной строке браузера: режим с хэштегами (по умолчанию) и режим HTML5, основанный на использовании HTML5 API истории. Приложения используют один и тот же API в обоих режимах, и сервис $location будет работать с соответствующими сегментами URL и API браузера для облегчения изменения URL браузера и управления историей.

Режим с хэштегами Режим HTML5
конфигурация по умолчанию { html5Mode: true }
формат URL URL с хэштегами во всех браузерах обычные URL в современных браузерах, URL с хэштегами в старых браузерах
переписывание ссылок <a href=""> нет да
требует конфигурации на стороне сервера нет да

Режим с хэштегами (режим по умолчанию)

В этом режиме $location использует 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. Это позволяет использовать обычные сегменты пути и поиска вместо их аналогов с хэштегами. Если API истории HTML5 не поддерживается браузером, сервис $location автоматически переходит к использованию URL с хэштегами. Это избавляет вас от необходимости беспокоиться о том, поддерживает ли браузер, отображающий ваше приложение, API истории или нет; сервис $location прозрачно использует наилучший доступный вариант.

  • Открытие обычного URL в устаревшем браузере -> перенаправление на URL с хэштегами
  • Открытие 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 предоставляет URL с хэштегами. Это освобождает вас от необходимости беспокоиться о том, поддерживает ли браузер, отображающий ваше приложение, API истории или нет; сервис $location делает это прозрачным для вас.

Переписывание ссылок Html

При использовании режима API истории HTML5 вам не понадобятся специальные ссылки с хэштегами. Все, что вам нужно сделать, это указать обычные ссылки 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>

Относительные ссылки

Убедитесь, что все относительные ссылки, изображения, скрипты и т. д. Angular требует указания базового URL в заголовке вашего основного HTML-файла (<base href="/my-base">) , если html5Mode.requireBase не установлено в false в объекте определения html5Mode, переданном в $locationProvider.html5Mode(). В этом случае относительные URL всегда будут разрешаться относительно этого базового URL, даже если начальный URL документа был другим.

Есть одно исключение: ссылки, содержащие только фрагмент хэштега (например, <a href="#target">), будут изменять только $location.hash() и не изменять URL иначе. Это полезно для прокрутки к якорям на той же странице без необходимости знать, на какой странице пользователь находится.

Серверная часть

Использование данного режима требует переписывания URL на стороне сервера, по сути, вам нужно переписать все ваши ссылки на точку входа в ваше приложение (например, index.html). Необходимость тега <base> также важна в этом случае, так как он позволяет Angular различать часть URL, которая является основой приложения, и путь, который должен обрабатываться приложением.

Пересылка ссылок между различными браузерами

Благодаря возможностям переписывания в режиме HTML5, ваши пользователи смогут открывать обычные URL-адреса в устаревших браузерах и ссылки с hashbang в современных браузерах:

  • Современные браузеры будут переписывать URL с hashbang на обычные URL.
  • Старые браузеры будут перенаправлять обычные URL на URL с hashbang.

Здесь вы можете увидеть два $location экземпляра, оба в режиме Html5, но в разных браузерах, чтобы вы могли увидеть различия. Эти $location службы подключены к фальшивым браузерам. Каждый вход представляет адресную строку браузера.

Обратите внимание, что при вводе URL с hashbang в первый браузер (или наоборот) он не переписывает/перенаправляет на обычный/hashbang URL, так как это преобразование происходит только во время парсинга начального URL = при перезагрузке страницы.

В этих примерах мы используем <base href="/base/index.html" />

Браузер в режиме HTML5

Браузер в режиме HTML5 отката (режим Hashbang)

Ограничения

Навигация при перезагрузке страницы

Служба $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() добавит прямую косую черту, если она отсутствует.

Обратите внимание, что префикс ! в режиме hashbang не является частью $location.path(); на самом деле это hashPrefix.

Обход вашего приложения

Чтобы разрешить индексацию вашего AJAX-приложения, вам необходимо добавить специальный тег meta в секцию 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 с hashbang (например, http://server.com/#!/path?search=a) при необходимости.

Изменения в вашем коде

Навигация внутри приложения Изменение на
$location.href = value
$location.hash = value
$location.update(value)
$location.updateHash(value)
$location.path(path).search(search)
$location.hashPath = path $location.path(path)
$location.hashSearch = search $location.search(search)
Навигация вне приложения Использовать API более низкого уровня
$location.href = value
$location.update(value)
$window.location.href = value
$location[protocol | host | port | path | search] $window.location[protocol | host | port | path | search]
Чтение Изменение на
$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

Поскольку $location использует геттеры/сеттеры, вы можете использовать ng-model-options="{ getterSetter: true }" для привязки к ngModel:

Связанный API

  • $location API

© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.3.20/docs/guide/$location

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API