Definir estilo de guia ativo com AngularJS

144

Eu tenho rotas definidas no AngularJS assim:

$routeProvider
    .when('/dashboard', {templateUrl:'partials/dashboard', controller:widgetsController})
    .when('/lab', {templateUrl:'partials/lab', controller:widgetsController})

Eu tenho alguns links na barra superior denominados guias. Como posso adicionar a classe 'ativa' a uma guia, dependendo do modelo ou URL atual?

Sergei Basharov
fonte
4
@AminMeyghani Como essa pergunta pode ser duplicada, que foi feita quase um ano depois ?
Regent

Respostas:

274

Uma maneira de resolver isso sem precisar confiar em URLs é adicionar um atributo personalizado a cada parcial durante a $routeProviderconfiguração, como este:

$routeProvider.
    when('/dashboard', {
        templateUrl: 'partials/dashboard.html',
        controller: widgetsController,
        activetab: 'dashboard'
    }).
    when('/lab', {
        templateUrl: 'partials/lab.html',
        controller: widgetsController,
        activetab: 'lab'
    });

Exponha $routeem seu controlador:

function widgetsController($scope, $route) {
    $scope.$route = $route;
}

Defina a activeclasse com base na guia ativa atual:

<li ng-class="{active: $route.current.activetab == 'dashboard'}"></li>
<li ng-class="{active: $route.current.activetab == 'lab'}"></li>
Rob Juurlink
fonte
3
esta é a melhor solução que eu já vi até agora porque suporta URLs dinâmicos como / foo /: bar.
martinpaulucci
3
Na verdade, não consegui fazer isso funcionar. você seria capaz de fornecer um plnkr?
PPPaul
9
Apenas uma coisa: melhor definir $scope.activeTab = $route.current.activetabpara que você possa manter o html um pouco mais limpo.
Christoph
2
Isso não funciona no AngularJS 1.0.8. $ route.current é indefinido.
Catfish
2
Combine isso com o $rootScopetruque de @ Lucas abaixo para disponibilizá-lo em todos os escopos.
colllin
134

Uma maneira de fazer isso seria usar a diretiva ngClass e o serviço $ location. No seu modelo, você pode fazer:

ng-class="{active:isActive('/dashboard')}"

onde isActiveseria uma função em um escopo definido assim:

myApp.controller('MyCtrl', function($scope, $location) {
    $scope.isActive = function(route) {
        return route === $location.path();
    }
});

Aqui está o jsFiddle completo: http://jsfiddle.net/pkozlowski_opensource/KzAfG/

Repetir ng-class="{active:isActive('/dashboard')}"em cada guia de navegação pode ser entediante (se você tiver muitas guias); portanto, essa lógica pode ser candidata a uma diretiva muito simples.

pkozlowski.opensource
fonte
1
Demorei muito tempo até encontrar 'diretivas muito simples' para ser realmente muito simples de escrever, por isso forneci uma abaixo. :-) Deve ser reutilizável em vários contextos, sem configuração não declarativa.
XML
1
Observando o jsFiddle, como você ativa a página atual no carregamento da página? O exemplo funciona apenas quando um usuário clica em uma opção. Por exemplo, você pode querer uma navegação 'doméstica' destacada ao desembarcar na página inicial a partir de um link externo.
thathurtabit
Ahh estava coçando minha cabeça por um tempo nisso. Obrigado!
masterwok
41

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.

XML
fonte
4
Eu não podia acreditar que ninguém realmente votou nisso! Aqui estão meus 2 centavos. Embora haja um pequeno erro no código, acho que o 'tabLevel' deve ser 'activeTab'. E para o estilo Bootstrap, você pode adicionar a classe 'active' ao elemento LI em vez do elemento A. Mas isso requer apenas pequenas alterações.
19413 David Lin
1
Você está absolutamente correto sobre o activeTab, @DavidLin. Editado. Mas não estou apaixonada pela estrutura do Bootstrap, daí uma diferença deliberada. De fato, estou começando a pensar que as abstrações nav podem não pertencer a ul's' e talvez devam ser apenas coleções de âncoras, envolvidas por um navou outro elemento de agrupamento. Lidar com a camada intermediária de lis é uma complexidade adicional sem retorno, principalmente agora que temos o navelemento à nossa disposição para deixar claro o que está acontecendo.
XML
Isso é simples e brilhante. Fiquei surpreso que não houvesse algo assim no Angular para verificar a rota em que você está.
Intellix
1
Para que funcione com o bootstrap3, tudo o que você precisa fazer é alterar `element.addClass (" active ");` para `element.parent ('li'). AddClass (" active ");` Eu acho que poderia ser melhor nomeado, porém, algo como is-active-tab insead of active-tab, que parece declarar que a guia está ativa. Caso contrário, esta é uma diretiva seriamente agradável. Veja esta alteração na resposta por @domi
boatcoder
A melhor solução desta página, não posso acreditar que tenha tão poucos votos positivos.
Karolis
27

@ rob-juurlink Melhorei um pouco sua solução:

em vez de cada rota precisar de uma guia ativa; e precisando definir a guia ativa em cada controlador eu faço isso:

var App = angular.module('App',[]);
App.config(['$routeProvider', function($routeProvider){
  $routeProvider.
  when('/dashboard', {
    templateUrl: 'partials/dashboard.html',
    controller: Ctrl1
  }).
  when('/lab', {
    templateUrl: 'partials/lab.html',
    controller: Ctrl2
  });
}]).run(['$rootScope', '$location', function($rootScope, $location){
   var path = function() { return $location.path();};
   $rootScope.$watch(path, function(newVal, oldVal){
     $rootScope.activetab = newVal;
   });
}]);

E o HTML fica assim. O activetab é apenas o URL relacionado a essa rota. Isso apenas elimina a necessidade de adicionar código em cada controlador (arrastar dependências como $ route e $ rootScope se esse for o único motivo pelo qual eles são usados)

<ul>
    <li ng-class="{active: activetab=='/dashboard'}">
       <a href="#/dashboard">dashboard</a>
    </li>
    <li ng-class="{active: activetab=='/lab'}">
       <a href="#/lab">lab</a>
    </li>
</ul>
Lucas
fonte
Muito obrigado por esta modificação. Muito agradável. Você tem alguma sugestão para definir uma guia ativa quando a página é carregada pela primeira vez?
Hairgami_Master 3/04
2
Depende do que você quer. normalmente você teria '/' url como seu controlador principal. Dessa forma, quando o usuário acessa seu URL, ele carrega esse controlador e define essa guia como ativa. No exemplo acima, eu não tenho um URL '/', portanto, se esse for o seu caso, basta adicionar um .otherwise () $ routeProvider. when ('/ dashboard', {templateUrl: 'parcials / dashboard.html', controlador: Ctrl1}). quando ('/ lab', {templateUrl: 'parcials / lab.html', controller: Ctrl2}). Caso contrário ({redirectTo: '/ dashboard'}); boa sorte!
Lucas
Muito obrigado @Lucas. Isso ajudou. Por algum motivo, tive que adicionar o símbolo # à minha rota principal - quando ('# /', {controller: FormsController, templateUrl: 'parcials / dashboard.html'}).
HairGami_Master
Eu prefiro assim. Ter um rootScope e fazer qualquer coisa em qualquer lugar
wrivas
16

Talvez uma diretiva como essa possa resolver o seu problema: http://jsfiddle.net/p3ZMR/4/

HTML

<div ng-app="link">
<a href="#/one" active-link="active">One</a>
<a href="#/two" active-link="active">One</a>
<a href="#" active-link="active">home</a>


</div>

JS

angular.module('link', []).
directive('activeLink', ['$location', function(location) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs, controller) {
            var clazz = attrs.activeLink;
            var path = attrs.href;
            path = path.substring(1); //hack because path does bot return including hashbang
            scope.location = location;
            scope.$watch('location.path()', function(newPath) {
                if (path === newPath) {
                    element.addClass(clazz);
                } else {
                    element.removeClass(clazz);
                }
            });
        }

    };

}]);
kfis
fonte
1
Observe que você deve usar $ observe se o href contiver uma expressão: docs.angularjs.org/guide/directive#Attributes . Veja o violino atualizado: jsfiddle.net/p3ZMR/10
Narretz 3/12/12
14

Solução mais simples aqui:

Como definir a classe ativa bootstrap navbar com o Angular JS?

Qual é:

Use o ng-controller para executar um único controlador fora da ng-view:

<div class="collapse navbar-collapse" ng-controller="HeaderController">
    <ul class="nav navbar-nav">
        <li ng-class="{ active: isActive('/')}"><a href="/">Home</a></li>
        <li ng-class="{ active: isActive('/dogs')}"><a href="/dogs">Dogs</a></li>
        <li ng-class="{ active: isActive('/cats')}"><a href="/cats">Cats</a></li>
    </ul>
</div>
<div ng-view></div>

e inclua no controllers.js:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}
Zymotik
fonte
2
concordou, de longe o mais fácil
Angelos
12

Eu recomendo usar o módulo state.ui, que não apenas oferece suporte a visualizações múltiplas e aninhadas, mas também facilita esse tipo de trabalho (código abaixo citado):

<ul class="nav">
    <li ng-class="{ active: $state.includes('contacts') }"><a href="#{{$state.href('contacts')}}">Contacts</a></li>
    <li ng-class="{ active: $state.includes('about') }"><a href="#{{$state.href('about')}}">About</a></li>
</ul>

Vale a pena ler.

David Lin
fonte
4

Aqui está outra versão da mudança de LI do XMLillies com domi que usa uma cadeia de pesquisa em vez de um nível de caminho. Eu acho que isso é um pouco mais óbvio do que está acontecendo no meu caso de uso.

statsApp.directive('activeTab', function ($location) {
  return {
    link: function postLink(scope, element, attrs) {
      scope.$on("$routeChangeSuccess", function (event, current, previous) {
        if (attrs.href!=undefined) { // this directive is called twice for some reason
          // The activeTab attribute should contain a path search string to match on.
          // I.e. <li><a href="#/nested/section1/partial" activeTab="/section1">First Partial</a></li>
          if ($location.path().indexOf(attrs.activeTab) >= 0) {
            element.parent().addClass("active");//parent to get the <li>
          } else {
            element.parent().removeClass("active");
          }
        }
      });
    }
  };
});

O HTML agora se parece com:

<ul class="nav nav-tabs">
  <li><a href="#/news" active-tab="/news">News</a></li>
  <li><a href="#/some/nested/photos/rawr" active-tab="/photos">Photos</a></li>
  <li><a href="#/contact" active-tab="/contact">Contact</a></li>
</ul>
Dave Rapin
fonte
3

Achei a resposta do XMLilley a melhor e mais adaptável e não intrusiva.

No entanto, eu tive uma pequena falha.

Para uso com o bootstrap nav, aqui está como eu o modifiquei:

app.directive('activeTab', 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" 
                                   active-tab="1">HOME</a></li> 
            */
            if(attrs.href!=undefined){// this directive is called twice for some reason
                // this var grabs the tab-level off the attribute, or defaults to 1
                var pathLevel = attrs.activeTab || 1,
                // this var finds what the path is at the level specified
                    pathToCheck = $location.path().split('/')[pathLevel],
                // this var finds grabs the same level of the href attribute
                    tabLink = attrs.href.split('/')[pathLevel];
                // now compare the two:
                if (pathToCheck === tabLink) {
                  element.parent().addClass("active");//parent to get the <li>
                }
                else {
                  element.parent().removeClass("active");
                }
            }
        });
      }
    };
  });

Eu adicionei "if (attrs.href! = Undefined)" porque essa função é chamada adequadamente duas vezes, a segunda vez produzindo um erro.

Quanto ao html:

<ul class="nav nav-tabs">
   <li class="active" active-tab="1"><a href="#/accueil" active-tab="1">Accueil</a></li>
   <li><a active-tab="1" href="#/news">News</a></li>
   <li><a active-tab="1" href="#/photos" >Photos</a></li>
   <li><a active-tab="1" href="#/contact">Contact</a></li>
</ul>
domi
fonte
NVM, foi minha culpa que isso foi chamado duas vezes. Eu acho que "if (attrs.href! = Undefined)" não é necessário.
domi
3

Exemplo de inicialização.

Se você estiver usando o Angulars built in routing (ngview), esta diretiva poderá ser usada:

angular.module('myApp').directive('classOnActiveLink', [function() {
    return {
        link: function(scope, element, attrs) {

            var anchorLink = element.children()[0].getAttribute('ng-href') || element.children()[0].getAttribute('href');
            anchorLink = anchorLink.replace(/^#/, '');

            scope.$on("$routeChangeSuccess", function (event, current) {
                if (current.$$route.originalPath == anchorLink) {
                    element.addClass(attrs.classOnActiveLink);
                }
                else {
                    element.removeClass(attrs.classOnActiveLink);
                }
            });

        }
    };
}]);

Supondo que sua marcação tenha a seguinte aparência:

    <ul class="nav navbar-nav">
        <li class-on-active-link="active"><a href="/orders">Orders</a></li>
        <li class-on-active-link="active"><a href="/distributors">Distributors</a></li>
    </ul>

Eu gosto disso, pois você pode definir o nome da classe que deseja em seu atributo.

Michael Falck Wedelgård
fonte
2

Você também pode simplesmente injetar o local no escopo e usá-lo para deduzir o estilo da navegação:

function IndexController( $scope, $rootScope, $location ) {
  $rootScope.location = $location;
  ...
}

Em seguida, use-o no seu ng-class:

<li ng-class="{active: location.path() == '/search'}">
  <a href="/search">Search><a/>
</li>
Der Hochstapler
fonte
não deveria ser $ root.location.path () na marcação?
Irshu
@ Irshu: Isso poderia ser mais limpo, mas a abordagem acima funcionou para mim também.
Der Hochstapler
2

uma maneira alternativa é usar ui-sref-active

Uma diretiva trabalhando ao lado de ui-sref para adicionar classes a um elemento quando o estado da diretiva relacionada ui-sref estiver ativo e removendo-as quando estiver inativo. O principal caso de uso é simplificar a aparência especial dos menus de navegação baseados em ui-sref, fazendo com que o botão de menu do estado "ativo" apareça diferente, distinguindo-o dos itens de menu inativos.

Uso:

ui-sref-active = 'class1 classe2 classe3' - as classes "class1", "class2" e "class3" são adicionadas ao elemento diretivo quando o estado do ui-sref relacionado está ativo e removido quando está inativo.

Exemplo:
dado o seguinte modelo,

<ul>
  <li ui-sref-active="active" class="item">
    <a href ui-sref="app.user({user: 'bilbobaggins'})">@bilbobaggins</a>
  </li>
  <!-- ... -->
</ul>

quando o estado do aplicativo é "app.user" e contém o parâmetro de estado "user" com o valor "bilbobaggins", o HTML resultante aparecerá como

<ul>
  <li ui-sref-active="active" class="item active">
    <a ui-sref="app.user({user: 'bilbobaggins'})" href="/users/bilbobaggins">@bilbobaggins</a>
  </li>
  <!-- ... -->
</ul>

O nome da classe é interpolado uma vez durante o tempo do link das diretivas (quaisquer alterações adicionais no valor interpolado são ignoradas). Várias classes podem ser especificadas em um formato separado por espaço.

Use a diretiva ui-sref-opts para passar opções para $ state.go (). Exemplo:

<a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
George Botros
fonte
Obrigado. É realmente útil quando se trabalha em estrutura iônica!
Avijit Gupta
1

Eu concordo com o post de Rob sobre ter um atributo personalizado no controlador. Aparentemente, não tenho representante suficiente para comentar. Aqui está o jsfiddle que foi solicitado:

amostra html

<div ng-controller="MyCtrl">
    <ul>
        <li ng-repeat="link in links" ng-class="{active: $route.current.activeNav == link.type}"> <a href="{{link.uri}}">{{link.name}}</a>

        </li>
    </ul>
</div>

exemplo app.js

angular.module('MyApp', []).config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/a', {
        activeNav: 'a'
    })
        .when('/a/:id', {
        activeNav: 'a'
    })
        .when('/b', {
        activeNav: 'b'
    })
        .when('/c', {
        activeNav: 'c'
    });
}])
    .controller('MyCtrl', function ($scope, $route) {
    $scope.$route = $route;
    $scope.links = [{
        uri: '#/a',
        name: 'A',
        type: 'a'
    }, {
        uri: '#/b',
        name: 'B',
        type: 'b'
    }, {
        uri: '#/c',
        name: 'C',
        type: 'c'
    }, {
        uri: '#/a/detail',
        name: 'A Detail',
        type: 'a'
    }];
});

http://jsfiddle.net/HrdR6/

jasontwong
fonte
Gosto da abordagem orientada a dados da lista de links. E alguns podem optar por mover o conjunto de links para um serviço / fábrica.
Grant Lindsay
1
'use strict';

angular.module('cloudApp')
  .controller('MenuController', function ($scope, $location, CloudAuth) {
    $scope.menu = [
      {
        'title': 'Dashboard',
        'iconClass': 'fa fa-dashboard',
        'link': '/dashboard',
        'active': true
      },
      {
        'title': 'Devices',
        'iconClass': 'fa fa-star',
        'link': '/devices'
      },
      {
        'title': 'Settings',
        'iconClass': 'fa fa-gears',
        'link': '/settings'
      }
    ];
    $location.path('/dashboard');
    $scope.isLoggedIn = CloudAuth.isLoggedIn;
    $scope.isAdmin = CloudAuth.isAdmin;
    $scope.isActive = function(route) {
      return route === $location.path();
    };
  });

E use o abaixo no modelo:

<li role="presentation" ng-class="{active:isActive(menuItem.link)}" ng-repeat="menuItem in menu"><a href="{{menuItem.link}}"><i class="{{menuItem.iconClass}}"></i>&nbsp;&nbsp;{{menuItem.title}}</a></li>
Yeshodhan Kulkarni
fonte
0

Eu precisava de uma solução que não exigisse alterações nos controladores, porque em algumas páginas renderizamos apenas modelos e não há nenhum controlador. Graças a comentaristas anteriores que sugeriram o uso, $routeChangeSuccesseu vim com algo assim:

# Directive
angular.module('myapp.directives')
.directive 'ActiveTab', ($route) ->
  restrict: 'A'

  link: (scope, element, attrs) ->
    klass = "active"

    if $route.current.activeTab? and attrs.flActiveLink is $route.current.activeTab
      element.addClass(klass)

    scope.$on '$routeChangeSuccess', (event, current) ->
      if current.activeTab? and attrs.flActiveLink is current.activeTab
        element.addClass(klass)
      else
        element.removeClass(klass)

# Routing
$routeProvider
.when "/page",
  templateUrl: "page.html"
  activeTab: "page"
.when "/other_page",
  templateUrl: "other_page.html"
  controller: "OtherPageCtrl"
  activeTab: "other_page"

# View (.jade)
a(ng-href='/page', active-tab='page') Page
a(ng-href='/other_page', active-tab='other_page') Other page

Não depende de URLs e, portanto, é muito fácil configurá-lo para qualquer sub-página etc.

szimek
fonte
0

Não me lembro onde encontrei esse método, mas é bem simples e funciona bem.

HTML:

<nav role="navigation">
    <ul>
        <li ui-sref-active="selected" class="inactive"><a ui-sref="tab-01">Tab 01</a></li> 
        <li ui-sref-active="selected" class="inactive"><a ui-sref="tab-02">Tab 02</a></li>
    </ul>
</nav>

CSS:

  .selected {
    background-color: $white;
    color: $light-blue;
    text-decoration: none;
    border-color: $light-grey;
  } 
cfranklin
fonte
0

Se você estiver usando o ngRoute (para roteamento), seu aplicativo terá uma configuração abaixo,

angular
  .module('appApp', [
    'ngRoute'
 ])
config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl',
        controllerAs: 'main'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl',
        controllerAs: 'about'
      })
}
});

Agora, basta adicionar um controlador nessa configuração, como abaixo,

angular
      .module('appApp', [
        'ngRoute'
     ])
    config(function ($routeProvider) {
        $routeProvider
          .when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl',
            activetab: 'main'
          })
          .when('/about', {
            templateUrl: 'views/about.html',
            controller: 'AboutCtrl',
            activetab: 'about'
          })
    }
    })
  .controller('navController', function ($scope, $route) {
    $scope.$route = $route;
  });

Como você mencionou a guia ativa na sua configuração, agora você só precisa adicionar a classe ativa na sua tag <li>ou <a>. Gostar,

ng-class="{active: $route.current.activetab == 'about'}"

O que significa que, sempre que o usuário clicar na página, isso identificará automaticamente a guia atual e aplicará a classe css ativa.

Eu espero que isso ajude!

imbond
fonte
-3

Vim aqui para a solução .. embora as soluções acima estejam funcionando bem, mas as consideram um pouco complexas e desnecessárias. Para as pessoas que ainda procuram uma solução fácil e organizada, a tarefa será executada perfeitamente.

<section ng-init="tab=1">
                <ul class="nav nav-tabs">
                    <li ng-class="{active: tab == 1}"><a ng-click="tab=1" href="#showitem">View Inventory</a></li>
                    <li ng-class="{active: tab == 2}"><a ng-click="tab=2" href="#additem">Add new item</a></li>
                    <li ng-class="{active: tab == 3}"><a ng-click="tab=3" href="#solditem">Sold item</a></li>
                </ul>
            </section>
MGA
fonte