Spec-Zone.ru › Angular.js 1.4

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

Сервис $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 нет да (с резервным вариантом для устаревших браузеров)
осознаёт корневой каталог/контекст, из которого загружено приложение нет - 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 - см. режим Hashbang
    requireBase:true - см. относительные ссылки
    по умолчанию: enabled:false

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

Режим Hashbang (режим по умолчанию)

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

  • Открытие обычного URL в устаревшем браузере -> перенаправление на URL Hashbang
  • Открытие URL Hashbang в современном браузере -> перезапись на обычный 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 Hashbang. Это освобождает вас от необходимости беспокоиться о том, поддерживает ли браузер, отображающий ваше приложение, 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 вашего приложения в заголовке основного файла HTML (<base href="/my-base/index.html">) , если html5Mode.requireBase не установлено в false в объекте определения html5Mode, переданном в $locationProvider.html5Mode(). В этом случае относительные URL всегда будут разрешаться по этому базовому URL, даже если исходный URL документа был другим.

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

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

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

Ограничения base href

Сервис $location не может работать должным образом, если текущий URL находится вне URL, указанного в качестве base href. Это может иметь скрытые и запутанные последствия...

Рассмотрим base href, заданный следующим образом: <base href="/base/"> (то есть приложение существует в папке с именем /base). URL /base фактически находится за пределами приложения (он ссылается на файл base, расположенный в корневой папке /).

Если вы хотите иметь возможность переходить к приложению через URL, такой как /base, то вы должны убедиться, что ваш сервер настроен на перенаправление таких запросов на /base/.

Для получения дополнительной информации см. https://github.com/angular/angular.js/issues/14018.

Отправка ссылок между различными браузерами

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

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

Здесь вы можете увидеть два $location экземпляра, которые демонстрируют разницу между режимом Html5 и Html5 Fallback mode. Обратите внимание, что для имитации различных уровней поддержки браузеров, экземпляры $location подключены к сервису fakeBrowser, который вам не нужно настраивать в реальных проектах.

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

В этих примерах мы используем <base href="/base/index.html" />. Вводные данные представляют адресную строку браузера.

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

Браузер в режиме HTML5 Fallback (режим 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, вам нужно добавить специальный тег мета в секцию 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, а затем использует полученную информацию для составления ссылок 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.4.14/docs/guide/$location

Spec-Zone.ru

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