Seguindo o conselho de Pavel de usar uma diretiva personalizada, aqui está uma versão que exige a adição de carga útil ao routeConfig, é super declarativa e pode ser adaptada para reagir a qualquer nível do caminho, simplesmente alterando a qual slice()você está prestando atenção. .
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");
}
});
}
};
});
Estamos alcançando nossos objetivos ouvindo o $routeChangeSuccessevento, em vez de colocar um $watchno caminho. Trabalho sob a crença de que isso significa que a lógica deve ser executada com menos frequência, pois acho que assiste a tiros em cada $digestciclo.
Chame-o passando seu argumento no nível do caminho na declaração da diretiva. Isso especifica em qual parte do $ location.path () atual você deseja comparar seu hrefatributo.
<li class="nav_tab"><a href="#/home" detect-active-tab="1">HOME</a></li>
Portanto, se suas guias reagirem ao nível base do caminho, defina o argumento '1'. Portanto, quando location.path () for "/ home", ele corresponderá ao "# / home" no diretório href. Se você tiver guias que devem reagir ao segundo nível, terceiro ou 11º do caminho, ajuste de acordo. Esse corte de 1 ou superior ignorará o nefasto '#' no href, que permanecerá no índice 0.
O único requisito é que você invoque um <a>, pois o elemento está assumindo a presença de um hrefatributo, que será comparado ao caminho atual. No entanto, você pode se adaptar com bastante facilidade para ler / gravar um elemento pai ou filho, se preferir chamar o <li>ou algo assim. Eu entendo isso porque você pode reutilizá-lo em muitos contextos, simplesmente variando o argumento pathLevel. Se a profundidade da leitura fosse assumida na lógica, você precisaria de várias versões da diretiva para usar com várias partes da navegação.
EDIT 18/3/14: A solução foi generalizada de maneira inadequada e seria ativada se você definisse um argumento para o valor de 'activeTab' que retornava com undefinedrelação a ambos $location.path()e ao elemento href. Porque: undefined === undefined. Atualizado para corrigir essa condição.
Enquanto trabalhava nisso, percebi que deveria haver uma versão que você pode declarar em um elemento pai, com uma estrutura de modelo como esta:
<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>
Observe que esta versão não se parece mais remotamente com o HTML no estilo Bootstrap. Mas, é mais moderno e usa menos elementos, por isso sou parcial. Esta versão da diretiva, além da original, agora está disponível no Github como um módulo suspenso que você pode declarar apenas como uma dependência. Eu ficaria feliz em melhorá-los, se alguém realmente os usar.
Além disso, se você quiser uma versão compatível com o bootstrap que inclua <li>'s', poderá usar o módulo Tabs angular-ui-bootstrap , que eu acho que saiu após este post original, e que talvez seja ainda mais declarativo do que este. É menos conciso para coisas básicas, mas fornece algumas opções adicionais, como guias desabilitadas e eventos declarativos que são acionados ao ativar e desativar.