Suivant Pavel conseils pour utiliser un personnalisé directive, voici une version qui nécessite l'ajout d'aucun de charge utile pour le routeConfig, est super déclarative, et peut être adapté à réagir à n'importe quel niveau de la voie, en changeant simplement qui slice()
de ce que vous faites attention à.
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");
}
});
}
};
});
Nous sommes à l'atteinte de ces objectifs par l'écoute de l' $routeChangeSuccess
événement, plutôt que de placer un $watch
sur le chemin. Je travail en vertu de la conviction que cela signifie que la logique doit exécuter en moins souvent, je pense que les montres de feu sur chaque $digest
cycle.
L'appeler en passant votre chemin au niveau de l'argument sur la directive de la déclaration. Ceci spécifie quelle partie de l'actuel emplacement$.path() vous voulez faire correspondre votre href
attribut contre.
<li class="nav_tab"><a href="#/home" detect-active-tab="1">HOME</a></li>
Donc, si vos onglets de réagir à la base au niveau du tracé, l'argument '1'. Ainsi, lorsque l'emplacement.path() est "/home", elle correspond à l'encontre de la "#/home" dans l' href
. Si vous avez des onglets qui doivent réagir à la deuxième, ou troisième, ou 11ème du chemin, ajuster en conséquence. Ce découpage à partir de 1 ou plus sera de contourner l'infâme '#' dans le href, qui vivent à l'indice 0.
La seule exigence est que vous appelez sur un <a>
,, que l'élément est en supposant la présence d'un href
d'attribut, il va comparer le chemin d'accès actuel. Cependant, vous pourriez adapter assez facilement à la lecture/écriture d'un parent ou d'un enfant de l'élément, si vous avez préféré invoquer sur l' <li>
ou quelque chose. Je creuse ce parce que vous pouvez ré-utiliser dans de nombreux contextes, en faisant simplement varier la pathLevel argument. Si la profondeur de lire de a été supposé dans la logique, vous auriez besoin de plusieurs versions de la directive, afin de l'utiliser avec plusieurs pièces de la navigation.
EDIT 3/18/14: La solution n'était pas suffisamment généralisée, et activer si vous avez défini un arg pour la valeur de 'activeTab" qui est retourné undefined
contre $location.path()
, et celle de l'élément href
. Parce que: undefined === undefined
. Mis à jour pour corriger cette condition.
Tout en travaillant sur ce, j'ai réalisé qu'il devrait y avoir une version, vous pouvez simplement déclarer sur un élément parent, avec un modèle de structure comme ceci:
<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>
Notez que cette version n'est plus resemble Bootstrap de style HTML. Mais, c'est plus moderne et utilise moins d'éléments, donc, je suis partie à l'. Cette version de la directive, en plus de l'original, sont maintenant disponibles sur Github comme un drop-in module, vous pouvez simplement déclarer en tant que dépendance. Je serais heureux de Bower-ize, si quelqu'un l'utilise.
Aussi, si vous voulez un bootstrap compatible version qui inclut <li>
s', vous pouvez aller avec le angular-ui-bootstrap Onglets du module, qui, je pense, est venu après l'original de ce post, et qui est peut-être encore plus déclaratif que celui-ci. C'est moins concis pour les trucs de base, mais vous donne quelques options supplémentaires, comme les handicapés onglets et les événements qui le feu sur les activer et les désactiver.