Удалить событие hashchange из Angular или предотвратить Angular от перезаписи якорных ссылок

У нас есть проект, который использует Angular, но только для аспекта привязки к UI/AJAX, а не для каких-либо функций маршрутизации или SPA.

Мы хотим использовать якорные ссылки (#section-2) в статьях, которые мы пишем в выбранной нами CMS, а также использовать привязывающие ссылки с других страниц (/my-page#section-C), но Angular переписывает их на #/section-2, который разбивает якорные ссылки, созданные CMS.

Невозможно увеличить CMS, чтобы изменить способ обработки привязных ссылок.

Возможно ли это:

  • Удалить привязку события hashchange из Angular? Я вижу, что это событие привязано к исходному файлу src/ng/browser.js, где он обрабатывает некоторые из маршрутизации и переписывания ссылок, но он находится внутри закрытия, поэтому он не может быть доступен напрямую (и мы связываемся с Angular с CDN поэтому невозможно изменить источник Angular, и мы не хотим поддерживать собственный "пользовательский" Angular источник).

  • Задайте опцию или вызовите метод конфигурации, который в конечном счете отключит весь аспект маршрутизации Angular и не позволяет переписывать какие-либо ссылки? (Или, есть ли способ не включать эту часть Angular, но все же сохранить функциональность контроллера /UI/AJAX?)

Заметьте, что я уже пробовал это:

$locationProvider.html5Mode(true)

Однако он делает все другие ссылки на сайте неработоспособными, потому что все ссылки передаются через Angular для обработки. Поэтому, если я ссылаюсь на домашнюю страницу (<a href="/">Home</a>) и нажимаю ссылку на html5mode on, ссылка ничего не делает.

Ответ 1

Как обходной путь (и, конечно, не лучшая практика), я закончил модификацию источника Angular, чтобы удалить переписывание URL.

Я сделал несколько изменений, но я считаю, что тот, который заставил ссылки привязки работать снова, добавлял оператор return; в строке 844 location.js в источнике Angular:

https://github.com/angular/angular.js/blob/master/src/ng/location.js#L844

Это короткое замыкание вокруг большей части функций перезаписи URL.

Я также полностью удалил строки 262-264 из browser.js, который удаляет крюк Angular в событии hashchange:

https://github.com/angular/angular.js/blob/master/src/ng/browser.js#L262-264

Это не повлияло ни на одну из функций привязки Angular, но это заставило ссылки привязки снова начать работать.

Ответ 2

Я считаю, что вы хотите $anchorScroll. См. Этот ответ: Как обрабатывать привязку привязки привязки в AngularJS

Вот пример того, как он будет работать. Хэш просто рассматривается как часть идентификатора:

app.controller('TestCtrl', function($location, $anchorScroll) {
   var vm = this;
   vm.scrollTo = function(id) {
      $location.hash(id);
      $anchorScroll();
   }
});

<a ng-click="vm.scrollTo('#foo')">Foo</a>

<div id="#foo">Here you are</div>

См. plunker, демонстрирующий $anchorScroll

С помощью маршрутизации вы можете изменить ссылку на:

<a href="#/test##foo">Test/Foo</a>

и добавьте это в конфигурацию запуска:

 $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    if($location.hash()) {
        $anchorScroll();  
    }
 });

Смотрите plunker, демонстрирующий прокрутку с маршрутизацией и $anchorScroll

Ответ 3

Angular $locationProvider.html5Mode с этим параметром rewriteLinks - это то, что вы ищете. Он поместит angular в режим, в котором $location все еще может использоваться для чтения и записи URL-адреса браузера, но он никогда не попытается захватить ссылки на клики и запустить маршрутизацию angular SPA.

например:

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

Ответ 4

После установки $locationProvider.html5Mode (true) вы также установили <base> в <head> вашего документа?

<html>
  <head>
    <base href="/">
  </head>
</html>

Посмотрите здесь:

"Есть 2 вещи, которые нужно сделать.

  • Настройка $locationProvider
  • Настройка базы для относительных ссылок

или здесь

Ответ 5

У меня была аналогичная проблема при использовании angular с wordpress и найдено действительно простое исправление. Все, что вам нужно сделать, это удалить все $location injection в контроллерах. Когда вы вводите $location service (независимо от того, используете вы его или нет), он захватывает # поведение.

Это означает, что вам нужно прокручивать все ваши контроллеры, директивы и т.д. и убедитесь, что служба определения местоположения не указана нигде.

НТН

Ответ 6

Но почему бы не использовать ng-route? это полностью решит ваши проблемы. используя Ng-маршруты, вы можете достичь следующего (что вам и нужно).

<a href="#" onclick="location.href='http://www.example.com/base/#section-A'; return false;"> Section A</a>

<a href="#" onclick="location.href='http://www.example.com/base/my-page#section-C'; return false;">Another page</a>

<a href="/other-base/another?search">external</a>

вот фрагмент app.js

app.config(function($locationProvider) {
  $locationProvider.html5Mode(true).hashPrefix('!');
})

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

При использовании режима API истории HTML5 вам не понадобятся специальные ссылки hashbang. Все, что вам нужно сделать, это указать регулярные URL-ссылки, например: <a href="/some?foo=bar">link</a>

Когда пользователь нажимает на эту ссылку,

В устаревшем браузере URL-адрес изменяется на /index.html#!/some?foo=bar

В современном браузере URL-адрес изменяется на /some?foo=bar

В следующих случаях ссылки не переписываются; вместо этого браузер выполнит полную перезагрузку страницы по исходной ссылке.

Ссылки, содержащие целевой элемент Пример: <a href="/ext/link?a=b" target="_self">link</a>

Абсолютные ссылки, которые переходят в другой домен Пример: <a href="#" onclick="location.href='http://angularjs.org/'; return false;">link</a>

Ссылки, начинающиеся с '/', которые приводят к другому базовому пути Пример: <a href="/not-my-base/link">link</a>

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

Обязательно проверьте все относительные ссылки, изображения, скрипты и т.д. Angular требует указать базу 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). Требование к тегу также важно для этого случая, так как позволяет Angular различать часть URL-адреса, которая является базой приложения, и путь, который должен обрабатывать приложение.

ngSource