У меня есть маршруты, установленные в AngularJS, как это:
$routeProvider
.when('/dashboard', {templateUrl:'partials/dashboard', controller:widgetsController})
.when('/lab', {templateUrl:'partials/lab', controller:widgetsController})
У меня есть несколько ссылок на верхней панели в виде вкладок. Как я могу добавить «активный» класс на вкладку в зависимости от текущего шаблона или URL?
javascript
html
angularjs
Сергей Башаров
источник
источник
Ответы:
Чтобы решить эту проблему, не полагаясь на URL-адреса, добавьте пользовательский атрибут к каждому частичному элементу во время
$routeProvider
настройки, например:Выставь
$route
в своем контроллере:Установите
active
класс на основе текущей активной вкладки:источник
$scope.activeTab = $route.current.activetab
чтобы вы могли держать HTML немного чище.$rootScope
уловкой @ Lucas's ниже, чтобы сделать ее доступной во всех областях.Один из способов сделать это - использовать директиву ngClass и службу $ location. В вашем шаблоне вы можете сделать:
где
isActive
будет функция в области видимости, определенной следующим образом:Вот полный jsFiddle: http://jsfiddle.net/pkozlowski_opensource/KzAfG/
Повторение
ng-class="{active:isActive('/dashboard')}"
на каждой вкладке навигации может быть утомительным (если у вас много вкладок), поэтому эта логика может быть кандидатом на очень простую директиву.источник
Следуя совету Павла об использовании пользовательской директивы, вот версия, которая не требует добавления полезной нагрузки к routeConfig, является супер декларативной и может быть адаптирована для реагирования на любой уровень пути, просто изменяя, на какой
slice()
из них вы обращаете внимание ,Мы достигаем наших целей, слушая
$routeChangeSuccess
событие, а не ставя$watch
на путь. Я работаю, полагая, что это означает, что логика должна работать реже, так как я думаю, что наблюдает огонь на каждом$digest
цикле.Вызовите его, передав аргумент уровня пути в объявлении директивы. Это указывает, с каким блоком текущего $ location.path () вы хотите сопоставить свой
href
атрибут.Итак, если ваши вкладки должны реагировать на базовый уровень пути, задайте аргумент «1». Таким образом, когда location.path () равен "/ home", он будет совпадать с "# / home" в
href
. Если у вас есть вкладки, которые должны реагировать на второй уровень, третий или одиннадцатый путь, скорректируйте их соответствующим образом. Это разделение от 1 или больше будет обходить гнусное «#» в href, которое будет жить с индексом 0.Единственное требование заключается в том, что вы вызываете для
<a>
, так как элемент предполагает наличиеhref
атрибута, который он будет сравнивать с текущим путем. Тем не менее, вы можете довольно легко адаптироваться для чтения / записи родительского или дочернего элемента, если вы предпочитаете вызывать его<li>
или что-то еще. Я копаю это, потому что вы можете использовать его во многих контекстах, просто меняя аргумент pathLevel. Если в логике предполагалась глубина чтения, вам понадобилось бы несколько версий директивы для использования с несколькими частями навигации.РЕДАКТИРОВАНИЕ 18.03.14: Решение было недостаточно обобщено и активировалось бы, если бы вы определили arg для значения 'activeTab', которое возвращалось
undefined
как$location.path()
для элемента, так и для элементаhref
. Потому что:undefined === undefined
. Обновлено, чтобы исправить это условие.Работая над этим, я понял, что должна быть версия, которую вы можете просто объявить в родительском элементе, со структурой шаблона, подобной этой:
Обратите внимание, что эта версия больше не напоминает HTML в стиле Bootstrap. Но он более современный и использует меньше элементов, поэтому я неравнодушен к этому. Эта версия директивы, а также оригинал теперь доступны на Github в качестве вставного модуля, который вы можете просто объявить как зависимость. Я был бы счастлив, чтобы Bower-ize их, если кто-то на самом деле использует их.
Кроме того, если вам нужна совместимая с начальной загрузкой версия, включающая в себя
<li>
, вы можете использовать модуль вкладок angular-ui-bootstrap , который, как мне кажется, появился после этой первоначальной публикации и, возможно, даже более декларативный, чем этот. Он менее лаконичен для базовых вещей, но предоставляет вам некоторые дополнительные опции, такие как отключенные вкладки и декларативные события, которые запускаются при активации и деактивации.источник
ul
's', и, возможно, они должны быть просто коллекциями якорей, обернутымиnav
или другим элементом группировки. Работа с промежуточным слоемli
's является дополнительной сложностью без какой-либо отдачи, особенно теперь, когдаnav
в нашем распоряжении есть элемент, чтобы прояснить, что происходит.@ rob-juurlink Я немного улучшил ваше решение:
вместо каждого маршрута нужна активная вкладка; и нужно установить активную вкладку в каждом контроллере, я делаю это:
И HTML выглядит так. Activetab - это просто URL, связанный с этим маршрутом. Это просто устраняет необходимость добавлять код в каждый контроллер (перетаскивание зависимостей, таких как $ route и $ rootScope, если это единственная причина, по которой они используются)
источник
Возможно, такая директива может решить вашу проблему: http://jsfiddle.net/p3ZMR/4/
HTML
JS
источник
Самое простое решение здесь:
Как установить загрузочный класс Navbar с Angular JS?
Который:
Используйте ng-controller для запуска одного контроллера за пределами ng-view:
и включите в controllers.js:
источник
Я рекомендую использовать модуль state.ui, который не только поддерживает множественные и вложенные представления, но и очень упрощает эту работу (код приведен ниже):
Стоит прочтения.
источник
Вот еще одна версия XML Lillies с изменением LI domi, которая использует строку поиска вместо уровня пути. Я думаю, что это немного более очевидно, что происходит для моего варианта использования.
HTML теперь выглядит так:
источник
Я нашел ответ XMLilley лучшим и наиболее адаптируемым и ненавязчивым.
Однако у меня был небольшой глюк.
Для использования с начальной загрузкой вот как я изменил его:
Я добавил «if (attrs.href! = Undefined)», потому что эта функция вызывается дважды, второй раз вызывая ошибку.
Что касается HTML:
источник
Пример начальной загрузки.
Если вы используете Angulars, встроенную в маршрутизацию (ngview), эту директиву можно использовать:
Предполагая, что ваша разметка выглядит так:
Мне нравится это делать, так как вы можете установить имя класса, которое вы хотите в своем атрибуте.
источник
Вы также можете просто вставить местоположение в область и использовать его для выведения стиля навигации:
Тогда используйте это в своем
ng-class
:источник
альтернативный способ - использовать ui-sref-active.
Директива, работающая вместе с ui-sref для добавления классов к элементу, когда состояние связанной директивы ui-sref активно, и удаление их, когда оно неактивно. Основной вариант использования - упростить особый внешний вид навигационных меню, опираясь на ui-sref, так как кнопка меню в «активном» состоянии выглядит по-другому, что отличает ее от неактивных пунктов меню.
Использование:
ui-sref-active = 'class1 class2 class3' - каждый из классов "class1", "class2" и "class3" добавляется в элемент директивы, когда состояние связанного ui-sref активно, и удаляется, когда он неактивен.
Пример:
учитывая следующий шаблон,
когда состояние приложения «app.user» и содержит параметр состояния «user» со значением «bilbobaggins», результирующий HTML-код будет выглядеть как
Имя класса интерполируется один раз в течение времени ссылки директив (любые дальнейшие изменения в интерполированном значении игнорируются). Несколько классов могут быть указаны в формате с разделением пробелами.
Используйте директиву ui-sref-opts для передачи параметров в $ state.go (). Пример:
источник
Я согласен с постом Роба о наличии специального атрибута в контроллере. Видимо, у меня недостаточно представителей, чтобы комментировать. Вот jsfiddle, который был запрошен:
образец HTML
образец app.js
http://jsfiddle.net/HrdR6/
источник
И используйте ниже в шаблоне:
источник
Мне нужно решение, которое не требует изменений в контроллерах, потому что для некоторых страниц мы только визуализируем шаблоны, а контроллера вообще нет. Благодаря предыдущим комментаторам, которые предлагали использовать,
$routeChangeSuccess
я придумал что-то вроде этого:Он не зависит от URL-адресов, поэтому его очень легко настроить для любых подстраниц и т. Д.
источник
Я не могу вспомнить, где я нашел этот метод, но он довольно прост и хорошо работает.
HTML:
CSS:
источник
Если вы используете ngRoute (для маршрутизации), то ваше приложение будет иметь конфигурацию ниже,
Теперь просто добавьте контроллер в этой конфигурации, как показано ниже,
Поскольку вы упомянули активную вкладку в своей конфигурации, теперь вам просто нужно добавить активный класс в свой тег
<li>
или<a>
. Подобно,Это означает, что всякий раз, когда пользователь нажимает на страницу, это автоматически идентифицирует текущую вкладку и применяет активный класс CSS.
Надеюсь, это поможет!
источник
Пришел сюда для решения .. хотя вышеупомянутые решения работают нормально, но нашли их немного сложными ненужными. Для людей, которые все еще ищут простое и аккуратное решение, оно отлично справится с этой задачей.
источник