Roteador de IU angular:Como faço para que a visualização pai fique “ativa” ao navegar para a visualização aninhada?

StackOverflow https://stackoverflow.com//questions/22054391

Pergunta

Estou trabalhando em um projeto que implementou o roteador UI e está usando ui-sref-active="active" para adicionar a classe ativa ao item do menu de navegação quando esse item for a rota atual.No entanto, quando você navega para uma visualização aninhada nessa visualização, o item de menu pai não fica mais ativo.Veja o seguinte Plunker:

http://plnkr.co/edit/2CoEdS?p=preview

Por padrão (ou se você clicar nela) a Rota 1 está "ativa".Ao clicar em “Mostrar lista”, você verá que a Rota 1 não está mais ativa.

Editar:

A única diferença entre este exemplo e meu projeto real é que o menu de navegação em meu projeto real possui seu próprio controlador e, portanto, não usa o mesmo escopo que o controlador para "rota1".

Foi útil?

Solução

EDIT Para ui-router 0.2.13 atualizado:

ui-sref-active="active" agora define a classe 'ativa' quando o estado atual é o estado do ui-sref ou qualquer criança

ui-sref-active-eq="active" se comporta como as iterações anteriores de ui-sref-active e apenas define a classe para o estado exato

Resposta Original:

Veja problemas abertos do roteador da interface do usuário:https://github.com/angular-ui/ui-router/issues/704 e 818

Uma solução alternativa geral que as pessoas estão sugerindo é:

ng-class="{active:$state.includes('route1')}"

Claro, $state deve ser adicionado a $scope.Veja o plunk atualizado: http://plnkr.co/edit/KHLDJP?p=preview

Outras dicas

Você está entendendo errado ui-sref-active = "active"

<li ui-sref-active="active"><a ui-sref="route1">Route 1</a></li>

Isso mostrará destaque especial de CSS somente quando você estiver no estado route1 (referência https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active).Este é o caso quando você clica na rota 1.Mas quando você clica em "Mostrar lista" você não está mais na rota1.Em vez disso, você está no estado "route1.list" .Você pode verificar isso escrevendo o código a seguir.Isto é estritamente para entender como o estado funciona.

js

controlador interno

$rootScope.currentState = $state.$current.name //using rootScope so that you can access the variable anywhere inside html

dentro de HTML

{{currentState}}

Se você observar atentamente a documentação do ui-sref-active, ela não apenas examinará stateName, mas também stateParams; portanto, quando você for para o subestado, ele não alterará mais o CSS.A partir do código-fonte fica mais claro.

 function update() {
        if ($state.$current.self === state && matchesParams()) {
          $element.addClass(activeClass);
        } else {
          $element.removeClass(activeClass);
        }// route1===route1.list will not be true.

para resolver o problema, lembre-se de que as variáveis ​​de escopo são herdadas em visualizações aninhadas.

controlador interno da rota.

$scope.route1Active = true;

em HTML

<li ng-class={active:route1Active}><a ui-sref="route1">Route 1</a></li>

O roteador Angular UI agora oferece suporte nativo para isso.Veja o commit https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

Minha solução foi definir:

<li ng-class="{ 'active': state.current.name.indexOf('route1') != -1 }">

O estado já foi adicionado anteriormente ao escopo do controlador:

$scope.state = $state;

Você não precisa fazer nada nos controladores.Aqui está meu código de exemplo:

    <ul class="nav nav-pills nav-stacked" role="tablist">
        <li ui-sref-active="active"><a ui-sref="Booking.Step1" href="#/Booking/Step1">Step1</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step2" href="#/Booking/Step2" >Step2</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step3" href="#/Booking/Step3">Step3</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step4" href="#/Booking/Step4">Step4</a></li>
        <li ui-sref-active="active"><a ui-sref="Booking.Step5" href="#/Booking/Step5">Step5</a></li>
    </ul>

Na configuração da rota:

$stateProvider.state('Booking', {
        abstract: true,
        url: '/Booking',
        templateUrl: "TourApp/Templates/Booking/SideMenu.html",
        controller: "SideMenuController"
    });

    $stateProvider.state('Booking.Step1', {
        url: "/Step1",
        views: {
            'content': {
                templateUrl: "TourApp/Templates/Booking/Step1.html",
                controller: "Step1Controller"
            }
        }
    });

    $stateProvider.state('Booking.Step2', {
        url: "/Step2",
        views: {
            'content': {
                templateUrl: "TourApp/Templates/Booking/Step2.html",
                controller: "Step2Controller"
            }
        }
    });

Agora eles foram atualizados e a nova maneira de fazer isso é

 <a ui-sref-active="{'active': 'main.app.manage.**'}" ui-sref="main.app.manage.people.list"></a>

Abaixo está o arquivo do estado

 angular.module('manage.people', ['people.invite'])
  .config(['$stateProvider', function($stateProvider) {
    $stateProvider
      .state('main.app.manage.people', {
        url: '/people',
        abstract: true,
        cache: false,
        views: {
          'tabContent': {
            template: '<div ui-view="peopleContent"></div>',
            controller: 'peopleController'
          }
        }
      })
      .state('main.app.manage.people.list', {
        url: '/list',
        views: {
          'peopleContent': {
            templateUrl: '/internal/main/app/manage/people/views/people.html',
            controller: 'peopleListController'
          }
        }
      });

Já temos uma solução sem nenhum “hack” AQUI

Essa é a maneira de fazer:

HTML >

 <li ui-sref-active="active" >
   <a href="#" class="submenu" ui-sref="bands">
       <i class="fa fa-location-arrow" aria-hidden="true"></i>
                     Bands
           <span class="fa fa-chevron-down"></span>
   </a>

   <ul class="nav child_menu">
        <li ui-sref-active="active">
            <a  ui-sref="bands.nirvana">
                 Nirvana   
            </a>
       </li>
       <li ui-sref-active="active">
            <a  ui-sref="bands.iron">
                Iron
            </a>
       </li>
       <li ui-sref-active="active">
            <a  ui-sref="bands.metalica">
                Metalica
            </a>
       </li>           
  </ul>

A configuração do nosso roteador ficará assim >

$stateProvider.state('bands', {
    abstract: true,
    url: '/bands',
    templateUrl: "myapp/categories/template.bands.html", //<ui-view></ui-view> 
    controller: "SomeController as vm"
}).state('bands.nirvana', {
    url: '/nirvana',
    templateUrl: "myapp/categories/band.nirvana.html",
    controller: "SomeController as vm"
}).state('bands.iron', {
    url: '/iron',
    templateUrl: "myapp/categories/band.iron.html",
    controller: "SomeController as vm"
}).state('bands.meatlica', {
    url: '/metalica',
    templateUrl: "myapp/categories/band.metalica.html",
    controller: "SomeController as vm"
})

Eu vim aqui 2 anos depois, a pergunta foi feita, mas angular-ui-router tem uma abordagem muito proficiente para resolver esse problema.Também funcionou para estados aninhados.

<ul>
  <li ui-sref-active="active" class="item">
    <a ui-sref="home">Home</a>
  </li>
  <!-- ... -->
</ul>

Quando o aplicativo navega para home estado, é assim que o HTML resultante aparecerá:

<ul>
  <li ui-sref-active="active" class="item active">
    <a ui-sref="home">Home</a>
  </li>
  <!-- ... -->
</ul>

referência rápida ui-sref-active:

Uma diretiva trabalhando ao lado da UI-SREF para adicionar classes a um elemento quando o estado da Diretiva de Ui-Sref relacionado estiver ativo e removê-las quando estiver inativo.O principal caso de uso é simplificar a aparência especial dos menus de navegação que confiam na UI-SREF, com o botão de menu do estado "ativo" parece diferente, distinguindo-o dos itens de menu inativos.

Documentação completa.

Espero que seja isso que você está procurando. Coloque o URL pai na classe da lista, agora sempre que você navegar para a classe filha, a classe pai estará ativa

Passo 1:Adicione um controlador para sua barra de navegação ou em seu controlador existente onde a barra de navegação está incluída, adicione o seguinte

app.controller('navCtrl', ['$scope', '$location', function($scope, $location) {
        $scope.isActive = function(destination) {
        return destination === $location.path();
    }

}]);

Passo 2:Na sua barra de navegação

<li ng-class="{active: isActive('/home')}"><a ui-sref="app.home">Browse Journal</a></li>

É isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top