Дотримуючись поради Павла використовувати користувальницьку директиву, ось версія, яка не потребує додавання корисного навантаження на routeConfig, є супердекларативною і може бути адаптована для того, щоб реагувати на будь-який рівень шляху, просто змінивши, на який slice()
із них ви звертаєте увагу. .
app.directive('detectActiveTab', function ($location) {
return {
link: function postLink(scope, element, attrs) {
scope.$on("$routeChangeSuccess", function (event, current, previous) {
/*
Designed for full re-usability at any path, any level, by using
data from attrs. Declare like this:
<li class="nav_tab">
<a href="#/home" detect-active-tab="1">HOME</a>
</li>
*/
// This var grabs the tab-level off the attribute, or defaults to 1
var pathLevel = attrs.detectActiveTab || 1,
// This var finds what the path is at the level specified
pathToCheck = $location.path().split('/')[pathLevel] ||
"current $location.path doesn't reach this level",
// This var finds grabs the same level of the href attribute
tabLink = attrs.href.split('/')[pathLevel] ||
"href doesn't include this level";
// Above, we use the logical 'or' operator to provide a default value
// in cases where 'undefined' would otherwise be returned.
// This prevents cases where undefined===undefined,
// possibly causing multiple tabs to be 'active'.
// now compare the two:
if (pathToCheck === tabLink) {
element.addClass("active");
}
else {
element.removeClass("active");
}
});
}
};
});
Ми досягаємо своїх цілей, слухаючи $routeChangeSuccess
подію, а не ставлячи $watch
на шлях. Я працюю, вважаючи, що це означає, що логіка повинна працювати рідше, так як я думаю, що дивиться вогонь на кожному $digest
циклі.
Викликайте його, передавши аргумент рівня шляху на декларацію директиви. Це визначає, з яким фрагментом поточного $ location.path () ви хочете співставити свій href
атрибут.
<li class="nav_tab"><a href="#/home" detect-active-tab="1">HOME</a></li>
Отже, якщо ваші вкладки повинні реагувати на базовий рівень шляху, зробіть аргумент "1". Таким чином, коли location.path () є "/ home", він буде відповідати "# / home" вhref
. Якщо у вас є вкладки, які повинні реагувати на другий рівень, або третій, або 11-й шлях, відрегулюйте відповідно. Це нарізання від 1 або більше обійде негідний '#' в href, який буде жити з індексу 0.
Єдина вимога полягає в тому, що ви посилаєтесь на <a>
, оскільки елемент припускає наявність href
атрибута, який він буде порівнювати з поточним контуром. Однак ви можете досить легко адаптуватись до читання / запису батьківського або дочірнього елемента, якщо ви хочете посилатися на <li>
щось або щось таке. Я копаю це, тому що ви можете повторно використовувати його у багатьох контекстах, просто змінивши аргумент pathLevel. Якщо глибина, яку слід читати, передбачалася логікою, вам знадобиться кілька версій директиви для використання з кількома частинами навігації.
EDIT 3/18/14: Рішення було неадекватно узагальнено, і воно активується, якщо ви визначите аргумент для значення "activeTab", яке повертається undefined
проти обох $location.path()
та елементів href
. Тому що: undefined === undefined
. Оновлено, щоб виправити цю умову.
Працюючи над цим, я зрозумів, що повинна бути версія, яку ви можете просто оголосити на батьківському елементі, із такою структурою шаблону:
<nav id="header_tabs" find-active-tab="1">
<a href="#/home" class="nav_tab">HOME</a>
<a href="#/finance" class="nav_tab">Finance</a>
<a href="#/hr" class="nav_tab">Human Resources</a>
<a href="#/quarterly" class="nav_tab">Quarterly</a>
</nav>
Зауважте, що ця версія вже не віддалено нагадує HTML у стилі Bootstrap. Але, він сучасніший і використовує менше елементів, тому я частково ставлюсь до цього. Ця версія директиви плюс оригінал тепер доступні на Github як модуль, що випадає, який ви можете просто оголосити як залежність. Я був би радий Бауер-Ізе їх, якщо хтось насправді ними користується.
Крім того, якщо ви хочете сумісну з завантажувальною версією версію, яка включає в себе <li>
s, ви можете перейти з модулем Tagular-ui-bootstrap Tabs , який, на мою думку, вийшов після цієї оригінальної публікації, і який, можливо, навіть більш декларативний, ніж цей. Він менш стислий для базових матеріалів, але надає вам деякі додаткові параметри, наприклад, вимкнені вкладки та декларативні події, які активуються та вимикаються.