Angular.js: инъекция $ location переписывает и разрывает якорные ссылки

Созданный на 23 окт. 2013  ·  74Комментарии  ·  Источник: angular/angular.js

Простое введение $ location в любое место вашего приложения приводит к разрыву якорных ссылок (которые до сих пор работали уже 20 лет !). Вот пример кода, демонстрирующего проблему: https://gist.github.com/skivvies/7125406

Вот ссылка на rawgithub, чтобы вы действительно могли запустить этот код: https://rawgithub.com/skivvies/7125406/raw/b42a135b7a40db7dc00a7726fa8efd080e14b7b7/index.html

Следите за адресной строкой браузера, когда нажимаете «ссылку для привязки». Сравните это почти с тем же кодом, с той лишь разницей, что $ location не вводится: https://gist.github.com/skivvies/7125477

Опять же, вот ссылка rawgithub на эту версию, чтобы вы могли ее запустить: https://rawgithub.com/skivvies/7125477/raw/1b4a4d2692616c42b92b813b4c7d1e26ffe38c9b/index.html

Этапы воспроизведения:

  1. Откройте новое окно браузера непосредственно для привязки на странице с приложением Angular, которое вводит $ location, например https://rawgithub.com/skivvies/7125406/raw/b42a135b7a40db7dc00a7726fa8efd080e14b7b7/index.html#anchor
  2. Angular захватывает хеш URL-адреса и переписывает его, добавляя ведущую косую черту, например https://rawgithub.com/skivvies/7125406/raw/b42a135b7a40db7dc00a7726fa8efd080e14b7b7/index.html#/anchor
  3. Браузер не прокручивает страницу вниз до привязки к привязке
  4. При нажатии на любую ссылку на странице, ведущую к привязке (например, ссылку «ссылка на привязку» в примере кода), также не удается прокрутить страницу до привязки.

(Я нажимаю это, потому что я использую директиву dropdown toggle angular-bootstrap, которая вводит $ location, я никогда не вставляю его в свое приложение, но просто в зависимости от angular-bootstrap достаточно, чтобы сломать мои якорные ссылки. Благодаря этому сообщение для предупреждения меня. / cc @ pkozlowski-opensource)

http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html выглядело многообещающим решением, но в конечном итоге не сработало. Обновление: см. Комментарии ниже.

Lots of comments $location moderate broken expected use bug

Самый полезный комментарий

Привет,

Я нашел решение этого кошмара, но я новичок в AngularJS и не знаю, правильное ли это решение.
Я включил html5mode вот так:

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

Теперь все ссылки работают как положено и ошибок на js нет.

Все 74 Комментарий

я тоже вижу эту проблему.

наблюдая точно такое же поведение.

Может быть, у вас будет время поработать пиар для этого приближения. Есть ли какие-нибудь указания от основной команды по этому поводу, прежде чем я углублюсь в него?

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

Вот суть с target = "_ self": https://gist.github.com/skivvies/8430668

А вот ссылка на rawgithub, чтобы вы могли попробовать:
https://rawgithub.com/skivvies/8430668/raw/e17b8cae60faaec3a07084d657c0eeaf47f8b3f3/index.html

При щелчке по ссылке область просмотра успешно прокручивается до
целевой якорь, но хеш URL-адреса изменен на # / якорь, а не

якорь, и, что еще хуже, Angular сломал кнопку возврата в браузере. (Если

у вас есть страница в вашей истории перед этой, нажав кнопку "Назад"
не приведет вас к этому, как следовало бы, а теперь ничего не сделает, кроме как вызвать
кратковременное мерцание.)

Так что это не полный обходной путь, но все же в некотором роде
улучшение. Спасибо за чаевые!

14 января 2014 г., 21:38, Ллайл ван Шалквик <
[email protected]> написал:

Похоже, что использование target = "_ self" помогает обойти проблему.

-
Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/angular/angular.js/issues/4608#issuecomment -32329769
.

Вероятно, потому что, когда он не находится в html5Mode, $ location предполагает, что вы используете маршрутизацию Angular и обрабатываете все ссылки "#" как таковые.

Итак, есть два варианта / обходных пути:

  1. Если вы используете ng-click для обновления $location.hash и вызываете $anchorScroll в $timeout , это, похоже, решает проблему: http://plnkr.co / edit / nzTBmWFKOMVkxrcJSiPW? p = предварительный просмотр
  2. Используйте html5Mode , и это также решает проблему: http://plnkr.co/edit/qAH0bPAMdUKRYblW6I6k?p=preview

Я предполагаю, что я говорю, что в момент использования $ location, если вы не в режиме HTML5, все после символа "#" является доменом Angular routing, и он будет вести себя иначе, чем вы могли бы ожидать.

Спасибо за комментарии, @blesh.

Я думаю, что первый предложенный обходной путь изменения каждого href на ng-click, который обновляет $ location.hash и вызывает $ anchorScroll в $ timeout, уродлив. Это требует отмены вашего действительного html для надежной попытки повторной реализации правильного поведения в javascript. Учитывая, что это работает в браузерах - без использования javascript - в течение последних 20 лет, я думаю, что приемлемый обходной путь не должен так резко противоречить структуре Интернета. Давайте не заставим Тима Бернерса-Ли прийти убить нас ночью!

Что касается второго предложения, я протестировал его, и недостаточно просто установить для html5Mode значение true, вам также нужно обновить все ваши привязанные ссылки, чтобы добавить target = "_ self", чтобы он работал, как вы это делали в своем плункере. . Это, по крайней мере, полный обходной путь (т.е. только с target = "_ self" и без html5Mode хэш URL-адреса будет неправильно иметь префикс /, как отмечалось ранее) и не нарушает работу Интернета, как это делает первое предложение. . Жаль, что вам нужно обновлять каждую ссылку привязки в своем приложении с помощью какой-то волшебной разметки, которая выглядит так, будто она ничего не дает кому-то еще, кто смотрит на код (или себя, 3 месяца спустя), но ИМО это намного лучше, чем жить с ошибкой или используя первое предложение.

Еще раз спасибо за комментарии. И все еще надеюсь когда-нибудь взломать патч, если меня никто не опередит.

Просто хотел добавить, еще одна метрика для обходного пути - это то, что вы сделаете после того, как исправленная ошибка будет фактически исправлена. В первом предложении, чтобы извлечь выгоду из исправления ошибки, вам нужно было бы вернуть все ng-clicks на правильные hrefs. Со вторым вы все еще можете воспользоваться исправлением, не удаляя все атрибуты target = "_ self", что можно было бы сделать позже, если нужно было выполнить более неотложную работу.

Я не уверен, как это можно исправить без большого рефакторинга маршрутизации, который может быть беспорядочным. Удачи.

Конечно, я мог ошибаться, я не слишком внимательно изучал этот код.

Хорошо, есть еще одно решение ...

<a href="#/#anchor">Go to the id, "anchor"</a>

Я подумал об этом и понял, что на самом деле $ location может использоваться только с маршрутизацией, и когда вы маршрутизируете, вы можете прокручивать до идентификаторов на странице со ссылками с помощью «хеша» на маршруте. поэтому URL-адрес ссылки похож на http://hostname/path/to/app/#/angular/route/#hashOnPage , что совпадает с /path/to/app/#/angular/route/#hashOnPage где hashOnPage - это идентификатор того, что вы хотите прокрутить. В зависимости от того, где вы находитесь, где находится приложение и какой маршрут вы в нем используете, вы можете использовать это, добавьте второй # чтобы добавить хеш к чему-то на экране ... Если это заставит смысл.

Это более эффективно решает вашу проблему?

В конце концов, вам действительно не следует использовать $location если вы не используете маршрутизацию. Так как это вроде того, на чем он построен.

Спасибо за дополнительную идею, @blesh. В случае, когда я нажал на это, я не использовал маршруты и вообще не нуждался в $ location. Я просто использовал angular-bootstrap для чего-то совершенно не связанного с маршрутизацией. Однако, поскольку одна из директив _its_ использовала $ location, она распространялась как вирус, нарушая якорные ссылки не только в моем приложении Angular, но даже на те, которые находятся за пределами элемента DOM с примененным ng-app. В идеале область, на которую влияет использование $ location, была бы более ограниченной, чтобы это не повлияло на код в удаленных и ничего не подозревающих местах.

Таким образом, ваш второй обходной путь по-прежнему лучше всего подходит для этого случая, когда вам не нужны $ location или маршрутизация, но некоторая зависимость, использующая его, портит ваши якорные ссылки.

Похоже, что angular-bootstrap больше не использует $ location с angular-ui / bootstrap @ 35c93076 (который также может исправить angular-ui / bootstrap # 619 - посмотрите, как текущее поведение $ location может вызывать подобные ошибки повсюду?) , поэтому для других пользователей angular-bootstrap, которым самим $ location (поднятием рук?) не требуется $ location (поднятие рук?), обновление до последней версии также должно избавить от этой ошибки, если ничто другое, чего они касаются, не использует $ location.

Спасибо также за ваши предупреждения о том, что исправление этого повлечет за собой большой рефакторинг маршрутизации, который может быть беспорядочным. Если это правда, то, вероятно, для основного разработчика имеет смысл вмешаться в эту тему, прежде чем менее опытный участник сообщества потратит много времени на исправление.

какие-нибудь обновления по решению этой проблемы? У меня также есть зависимости модуля, которые включают $ location, поэтому все мои якорные ссылки не работают.

Все еще надеюсь услышать мнение основного разработчика, прежде чем делать ставку на PR, поскольку похоже, что для слияния потребуется координация.

Также только что заметил, что в какой-то момент этап был изменен с «1.2.x» на «backlog». Означает ли это, что в ближайшее время он не попадет в релиз? / cc @btford

@skivvies , этап отставания на самом деле просто означает, что мы не активно настаиваем на том, чтобы

Хорошее начало с этого - предоставить тест ядра angular, который не работает, воспроизводя проблему минимальным образом. В противном случае предоставьте репродукцию проблемы на plnkr или jsbin или что-то в этом роде. Я думаю, что в системе отслеживания проблем, такой как хром, вы бы назвали это «неподтвержденным», нам действительно нужно убедиться, что это не работает должным образом.

(Это только мое личное мнение и не обязательно отражает мнение команды Angular)

fyi, это мой обходной путь. обратные ссылки по-прежнему работают, и нет необходимости менять мой html.

единственная проблема заключается в том, что он создает многословие в строке запроса. пример: mySite.com/page.html#/anchor#anchor

поместите внутрь $ scope-on-location-change-start:

if($location.hash() && $location.hash().length>=1)
{
var path = $location.path();
var potentialAnchor = path.substring(path.lastIndexOf("/")+1);
if ($("#" + potentialAnchor).length > 0) {                          
    $location.hash(potentialAnchor);
    $anchorScroll();
}
}

edit: и я тестировал его до ie8, все еще там работает.

@caitp написал:

Хорошее начало с этого - предоставить тест ядра angular, который не работает, воспроизводя проблему минимальным образом. В противном случае предоставьте репродукцию проблемы на plnkr или jsbin или что-то в этом роде. Я думаю, что в системе отслеживания проблем, такой как хром, вы бы назвали это «неподтвержденным», нам действительно нужно убедиться, что это не работает должным образом.

Похоже, вы пропустили описание билета. Вы увидите там ссылки на минимальное воспроизведение. Этот вопрос точно не подтвержден. Я считаю, что @btford подтвердил это и был тем, кто изначально планировал его для 1.2.x.

Тем не менее, отправка PR с неудавшимся модульным тестом - отличная идея. Я уже потратил много времени на подготовку описания проблемы. Может ли кто-нибудь еще подойти и написать тест?

Спасибо.

@ jasons-novaleaf написал:

fyi, это мой обходной путь. обратные ссылки по-прежнему работают, и нет необходимости менять мой html. единственная проблема заключается в том, что он создает многословие в строке запроса. пример: mySite.com/page.html#/anchor#anchor

Если вы используете этот обходной путь, если вы не хотите разорвать свои ссылки после устранения проблемы (или, возможно, написать устаревший код, чтобы перенаправить их обратно), вам придется продолжать использовать эти подробные строки запроса даже после устранения проблемы. . Поэтому я предпочитаю обходной путь: добавить target = "_ self" к якорным ссылкам и убедиться, что html5Mode истинно. Таким образом, вы получите красивые, чистые, нормально выглядящие якорные ссылки как до, так и после исправления. (И кнопка назад по-прежнему работает.)

Спасибо, что поделились!

@skivvies , на самом деле я уже некоторое время обращаю внимание на эту

Но да, причина, по которой вы не видите пиар, плз! status обычно объясняется тем, что пока не было доказано, что это реальная проблема. Если мы точно знаем, что это проблема, то мы определенно скажем: «Пожалуйста, внесите исправление для этого. Возможно, мы не будем прилагать усилий, чтобы включить это в следующий выпуск, но если кто-то предложит исправление, другие вещи плохо ломаются, они, наверное, хорошие "

Опять же, я перефразирую, но это действительно то, что я видел в этом выпуске в течение последних нескольких месяцев.

Вау, хорошо, для меня это стало полной неожиданностью. https://gist.github.com/skivvies/7125406 мне кажется минимальным воспроизведением, которое вы можете получить. И поведение при беге кажется неопровержимо нарушенным.

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

По крайней мере, согласны ли вы, что поведение https://gist.github.com/skivvies/7125406 является достаточно неожиданным, чтобы гарантировать, что некоторая документация предупреждает пользователей об этом?

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

Я думаю, вы могли бы сказать, что это ошибка, когда не создается экземпляр $ location при начальной загрузке, но это вроде не связано

Да, это так, поскольку вы все равно увидите ошибку, если создадите экземпляр $ location в
бутстрап. Таким образом, если этого не сделать, воспроизведение будет минимальным.

В пятницу, 7 февраля 2014 г., в 13:19 Кейтлин Поттер [email protected] написала :

Я думаю, вы могли бы сказать, что это ошибка, когда не создается экземпляр $ location на
бутстрап, но это не имеет отношения к

Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/angular/angular.js/issues/4608#issuecomment -34482945
.

Создание экземпляра местоположения при начальной загрузке также не приведет к тому, что ссылка на именованный якорь будет работать должным образом, поскольку перезаписанный URL-адрес попадает в SPA и предотвращает поведение по умолчанию. В html5mode мы могли бы правильно видеть хэш-фрагмент (разговоры о слиянии $ anchorScroll с $ location могли бы исправить это), но он будет работать непоследовательно в режиме hashbang, поэтому это своего рода проблематично.

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

Верно, это то, что я имел в виду, говоря «вы все равно увидите ошибку, если создадите экземпляр $ location при начальной загрузке», но спасибо за дополнительную информацию и ясность. Хорошо, чтобы было понятнее, что обходной путь, требующий установки для html5Mode значения true, не будет работать в браузерах, которые не поддерживают html5Mode.

Интересно, что есть разговоры о слиянии $ anchorScroll и $ location, я не слышал об этом.

Это действительно должно быть исправлено. Я не понимал, что добавление angular bootstrap на мой сайт нарушит навигацию по сайту. Я тоже не могу придумать обходной путь.

fyi, похоже, что мой обходной путь только наполовину работает с кнопками возврата. не уверен, почему .. во всяком случае. да, это нужно исправить :(

Хорошо, я попробую исправить для 1.3, но я не уверен, насколько сложно это будет исправить, поэтому ...

@caitp Отлично, спасибо! После того, как вы погрузитесь, если вы увидите, как это должно быть сделано, но у вас нет времени сделать это сразу, если вы оставите схему того, как вы хотите, чтобы это было исправлено, возможно, у меня или другого члена сообщества будет время отправить PR .

@ shawn-simon et al. Большое спасибо за поддержку этого вопроса. Что касается обходного пути, я думаю, что в идеале обходной путь не потребовал бы изменения каких-либо атрибутов «href» или чего-либо еще, что вам просто нужно было бы снова изменить, как только исправление появится. Поэтому я думаю, что обходной путь target = "_ self" + html5mode по-прежнему является лучшим (если вы можете позволить себе не поддерживать браузеры до HTML5).

Я думаю, что шаг 1) гарантирует, что $ location вводится при начальной загрузке, чтобы поведение библиотеки было согласованным.

Шаг 2) обрабатывает теги привязки по-разному (IE, если HREF начинается с символа '#', игнорируйте его).

Если это не сработает, в основном должно произойти слияние $ anchorScroll с $ location, и это уже обсуждалось.

Я полностью не знаю, сколько работы потребуется, чтобы заставить это работать, но посмотрим.

идея: вы можете сохранить текущую функциональность без изменений (чтобы избежать побочных эффектов), но исправить эту проблему для таких людей, как мы, сделав что-то вроде:

1) проверьте, начинается ли строка запроса со значения $ location.hashPrefix ()
2) если нет, игнорируйте это.
3) если да, то выполните текущий рабочий процесс.

так люди, как я, которые устанавливают

$location.hashPrefix('!');

будут работать якорные ссылки. где люди, использующие hashPrefix по умолчанию (пусто), увидят текущее поведение.

Он не будет объединен до версии 1.3.x (так что критические изменения в порядке), и я хочу, чтобы поведение было согласованным. В идеале ссылки пути должны работать в режиме hashbang, поэтому достаточно начать с # , чтобы сказать "игнорировать его".

ng-include требует, но необязательно использует $ anchorScroll, который извлекает $ location. Это означает, что, просто использовав ng-include один раз, мне теперь нужно переписать все свои теги привязки.

Это нарушение или, по крайней мере, абсурдно тупое поведение. Более чем рад помочь. Дайте мне знать, если это поможет большему количеству людей.

6899 потенциально исправляет это, когда включен html5Mode, но я не уверен. Я не собираюсь закрывать проблему, потому что она достаточно отдельная, но кто-то должен проверить это и подтвердить для меня, это было бы очень полезно.

Привет @caitp!

Вот вилка исходной сути, демонстрирующая ошибку, с последним моментальным снимком angular (1.3.0-build.2608 + sha.49e7c32), заменяющим angular 1.2.9, и ошибка все еще возникает:

https://rawgit.com/skivvies/11025788/raw/38e62189d6072c6cb83b049582a833a62bf5d747/index.html

Похоже, что изменения от # 6899, которые вы упомянули, попали бы в этот снимок, но, пожалуйста, дайте мне знать, нужно ли мне тестировать с другой версией angular.

Спасибо и воодушевлен тем, что в этом может быть еще прогресс.

@skivvies спасибо за ответ! К сожалению, работа над ним еще не завершена :( Там есть дополнение к этому на # 7152. Я думаю, что тесты должны пройти сейчас в нем, и теперь он должен работать лучше с современными браузерами.

Вы можете попробовать этот патч и посмотреть, решит ли он это (с включенным html5Mode). По-прежнему не уверен, что это сработает, потому что я думаю, что мы все еще предотвращаем поведение по умолчанию и не просим $ anchorScroll выполнить свою задачу. Так что это, вероятно, не исправит якорные ссылки. Но сейчас должно быть намного проще заставить их работать, по крайней мере, для html5Mode.

Было бы замечательно, если бы команда AngularJS поместила запись об этой проблеме в документацию. Я просто потерял день, просматривая свои правила перезаписи, пытаясь выяснить, почему мои ссылки были сломаны, прежде чем я понял, что это связано с angular.

Я чувствую твою боль @halleycarleton. Именно этого я и боялся с этим вопросом. Три месяца назад я сказал:

По крайней мере, согласны ли вы, что поведение https://gist.github.com/skivvies/7125406 является достаточно неожиданным, чтобы гарантировать, что некоторая документация предупреждает пользователей об этом?

Но дальнейшее обсуждение никогда не указывало на то, что исправление документации будет принято. @caitp , поскольку неясно, как скоро это будет исправлено, вы тем временем примете исправление документации об этой ошибке?

Как лучше всего проверить, что это меня ударило? Мне действительно нужно использовать $ location в блоке запуска моего приложения, а также я использую Angular Bootstrap. Я пробовал обновить Bootstrap до 0.11 и даже временно комментировать использование $ location, но без кубиков.

Кнопка "Назад" работает ... изредка у меня. Это не работало, когда я впервые начал работу над приложением (это мое первое приложение на Angular), и оно начало работать внезапно в какой-то момент без каких-либо сознательных или приписываемых мне изменений. Очевидно, я что-то изменил, но не знаю что. В последние несколько недель он, кажется, снова испортился.

Я нигде не могу найти помощи, чтобы заставить кнопку возврата работать в моей ситуации. Не знаю, к чему приписать взлом. Думаю, скоро я начну охоту на смехотворном уровне детализации, но я не вижу никаких красных флажков ...

FWIW, мы тоже застряли на 1.2, поэтому перенос на 1.3 не является для нас подходящим решением.

Исправлена ​​ли проблема в версии 1.3.x? IIRC у него тоже есть эта проблема.

Попал в эту ошибку. все неугловые ссылки ломаются. Есть ли какой-нибудь план исправить это?

Чтобы справиться с этой проблемой, я использую директиву, которая меняет якорные ссылки на полные URL-адреса, возможно, кто-то сочтет это полезным: https://gist.github.com/dcadenas/566434ba0af9f3eabb07

Для этого есть пиар, вот рабочая демонстрация http://plnkr.co/edit/WVPYzaXOKujcb5vSbvJz?p=preview

Это не идеально (работает только для относительных ссылок на фрагменты хэша), но это хорошее начало --- не стесняйтесь высказывать свои мысли

Я не думаю, что это ограничивается только интерактивностью якорных ссылок. Если я попытаюсь просто обновить example.com#param , оно также будет сброшено на example.com#/param .

@caitp где этот пиар? Как дела?

8508 --- он заблокирован для восстановления некоторых вещей, о чем я завтра говорю с Игорем.

K. Я работаю над небольшой записью в документации для https://docs.angularjs.org/guide/ $ location прямо сейчас - думаю, что это необходимо, или мне следует подождать?

Я имею в виду, вы могли бы поработать над этим - вы должны увидеть, исправляет ли связанная мной CL первую проблему, о которой вы говорите, потому что я сомневаюсь, что это будет (по крайней мере, в режиме hashbang) - возвращенный коммиты действительно влияют только на нажатие на якорные ссылки

@caitp Отправил PR, если хотите вкратце его проверить. Я проверил вашу ветку - отлично справился с моей проблемой, на этом спасибо. С нетерпением жду встречи с этим.

Угу ... Забыл выключить html5mode. Не работает, если он отключен. Еще нужно немного поработать. : /

да я думаю это отдельная ошибка

Хорошо. Могу ли я открыть для этого билет?

Конечно

Есть ли какие-либо обновления по этой ошибке, и основная ли команда все еще открыта для PR, чтобы исправить эту функциональность (даже если это дико критическое изменение)?

@samccone , @tbosch исправили это.

@caitp есть ссылка на

22948807e324eb0b182b15b31045dc306a9f3231 (и множество других связанных коммитов) - большое исправление

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

ах да, там это исправлено, просто жду релиза 1.2.x этого.

Спасибо!

Ой! >. <2 дня выясняю, почему не сработало. Я рад, что это также идет в 1.2.x: +1:. Есть идеи, когда он будет выпущен?

установите target = "_ self" в каждом теге привязки. Этот способ обхода мне подходит.

set target = "_ self" исправить мою проблему. Спасибо :)

установка target = "_ self" устраняет проблему только внутри самого сайта. Если вы хотите создать ссылку извне на якорную ссылку, все еще есть эта ужасная косая черта (угон angular) прямо внутри вашей гиперссылки. Это ужасно!

Я использую версию 1.3.9, и она пока не работает. Почему люди говорят, что это было исправлено в 1.2 ??

@wobine Мы не говорили, что это было исправлено в

Мне удалось заставить якоря работать правильно, используя следующую настройку (он учитывает только якоря идентификатора и, вероятно, портит угловую маршрутизацию для более сложных случаев использования)

module.config([ '$anchorScrollProvider', function($anchorScrollProvider) {
    $anchorScrollProvider.disableAutoScrolling();
}])
.run(['$rootScope', '$location', function($rootscope, $location) {
    // mimic the anchor behaviour, avoid using the $anchorScroll service
    $rootscope.$on('$locationChangeSuccess', function() {
        var element = $('#' + $location.url().replace('/', ''));
        if(element.length > 0) element[0].scrollIntoView();
    });
}]);

Привет,

Я нашел решение этого кошмара, но я новичок в AngularJS и не знаю, правильное ли это решение.
Я включил html5mode вот так:

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

Теперь все ссылки работают как положено и ошибок на js нет.

Я обошел это, используя событие ng-click с командой window.open (url):

<a class="viewLink" href ng-click="linkViewed()">

$scope.mediaViewed = function linkViewed() { window.open($scope.link) }

Я могу подтвердить, что ручной ответ работает должным образом с AngularJS v1.3.13.

Единственная проблема заключается в том, что когда я напрямую загружаю, например, http://site.com/#test, и снова нажимаю на #test, конечный URL-адрес - http://site.com/#test #test.

@manutalcual , ваше решение решило эту проблему.

Еще +1 за решение @manutalcual . Учитывая значение angular-bootstrap, также, вероятно, стоит отметить, что я использую 0,13.0 из этого, что включает в себя это изменение, упомянутое в разговоре выше.

14315 $ anchorScroll разрывает якорные ссылки при включенном html5mode

Это мой обходной путь:
Директива остановки распространения события с высоким приоритетом

var app = angular.module('my.module', []);

app.directive('externalAnchorLink', [function () {
    return {
        restrict: 'A',
        priority: 0,
        link: function (scope, el) {
            /*jslint unparam: true*/
            el.on('click', function (event) {
                event.stopPropagation();
            });
        }
    };
}]);

Затем в HTML

<a href="/test/example/#my-anchor" external-anchor-link>link text</a>

Что касается исходной проблемы ( $location влияет на поведение якорных ссылок по умолчанию):

Действительно, Angular использует # (возможно, с хеш-префиксом после # ) для идентификации «клиентского» маршрута (в режиме, отличном от HTML5). Задача $location - взаимодействовать с хеш-частью URL-адреса. Итак, поскольку невозможно отличить #some-client-side-route-path от #i-want-to-scroll-to-an-element , он всегда должен предполагать, что это путь маршрута на стороне клиента.

Доступно несколько решений (большинство из них обсуждались выше) - особенно если вы не используете $location / маршрутизацию на стороне клиента в своем приложении (но могут иметь зависимости, которые создают его экземпляр):

  1. Используйте пустой путь и хэш маршрута на стороне клиента: href="##i-want-to-scroll-to-an-element" .
  2. Настройте $locationProvider для использования режима HTML5
  3. Измените хэш-префикс (который по умолчанию пуст), чтобы #foo не распознавался как путь маршрута на стороне клиента. Например, с $locationProvider.hashPrefix('!') , клиентский маршрут должен начинаться с #! (например, #!foo ). Таким образом, #foo не распознается как путь, и применяется обычное поведение браузера.

Примечание. Начиная с версии 1.6, префиксом хэша по умолчанию будет ! , поэтому вариант использования OP будет работать по умолчанию (без необходимости вручную вызывать $locationProvider.hashPrefix('!') ). В более старых версиях вам нужно настроить его самостоятельно.

Я понимаю, что в этом выпуске может обсуждаться несколько проблем, но это не помогает с их оценкой, исследованием и, надеюсь, их исправлением, поэтому (поскольку исходная проблема относится к категории _fixed _ / _ работает как ожидалось_), я собираюсь закрыть эту проблему . Если вы по-прежнему сталкиваетесь с другими проблемами (о которых еще не сообщалось), откройте отдельные проблемы.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги