Mengikuti saran Pavel untuk menggunakan arahan khusus, berikut adalah versi yang tidak perlu menambahkan payload ke routeConfig, super deklaratif, dan dapat diadaptasi untuk bereaksi pada level jalan apa pun, hanya dengan mengubah yang mana slice()
Anda perhatikan. .
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");
}
});
}
};
});
Kami mencapai tujuan kami dengan mendengarkan $routeChangeSuccess
acara, bukan dengan menempatkannya $watch
di jalur. Saya bekerja di bawah keyakinan bahwa ini berarti logika harus berjalan lebih jarang, karena saya pikir jam tangan menyala pada setiap $digest
siklus.
Aktifkan itu dengan meneruskan argumen level jalan Anda pada deklarasi direktif. Ini menentukan potongan apa dari $ location.path () saat ini yang ingin Anda cocokkan dengan href
atribut Anda .
<li class="nav_tab"><a href="#/home" detect-active-tab="1">HOME</a></li>
Jadi, jika tab Anda bereaksi terhadap level dasar jalur, buat argumen '1'. Jadi, ketika location.path () adalah "/ home", itu akan cocok dengan "# / home" di href
. Jika Anda memiliki tab yang seharusnya bereaksi ke tingkat kedua, atau ketiga, atau ke 11 jalur, sesuaikan. Pemotongan dari 1 atau lebih ini akan mem-bypass '#' jahat di href, yang akan hidup pada indeks 0.
Satu-satunya persyaratan adalah bahwa Anda memanggil pada <a>
, karena elemen tersebut mengasumsikan keberadaan href
atribut, yang akan dibandingkan dengan jalur saat ini. Namun, Anda dapat beradaptasi dengan cukup mudah untuk membaca / menulis elemen induk atau anak, jika Anda lebih suka memohon pada <li>
sesuatu atau sesuatu. Saya menggali ini karena Anda dapat menggunakannya kembali dalam banyak konteks hanya dengan memvariasikan argumen pathLevel. Jika kedalaman untuk membaca diasumsikan dalam logika, Anda perlu beberapa versi dari direktif untuk digunakan dengan beberapa bagian navigasi.
EDIT 3/18/14: Solusinya tidak cukup digeneralisasi, dan akan aktif jika Anda mendefinisikan argumen untuk nilai 'activeTab' yang mengembalikan undefined
keduanya $location.path()
, dan elemen href
. Karena: undefined === undefined
. Diperbarui untuk memperbaiki kondisi itu.
Saat mengerjakannya, saya menyadari seharusnya ada versi yang bisa Anda deklarasikan pada elemen induk, dengan struktur template seperti ini:
<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>
Perhatikan bahwa versi ini tidak lagi menyerupai HTML gaya Bootstrap. Tapi, ini lebih modern dan menggunakan lebih sedikit elemen, jadi saya tidak setuju. Versi direktif ini, plus yang asli, sekarang tersedia di Github sebagai modul drop-in yang bisa Anda nyatakan sebagai dependensi. Saya akan senang untuk Bower-ize mereka, jika ada yang benar-benar menggunakannya.
Juga, jika Anda menginginkan versi yang kompatibel dengan bootstrap yang menyertakannya <li>
, Anda dapat menggunakan modul angular-ui-bootstrap Tab , yang saya pikir keluar setelah posting asli ini, dan yang mungkin bahkan lebih deklaratif daripada yang ini. Ini kurang ringkas untuk hal-hal dasar, tetapi memberi Anda beberapa opsi tambahan, seperti tab yang dinonaktifkan dan acara deklaratif yang diaktifkan dan dinonaktifkan.