web-dev-qa-db-fra.com

Angular UI Router (Routeur d’interface utilisateur angulaire): Comment "rendre actif" la vue parent lorsque vous accédez à une vue imbriquée?

Je travaille sur un projet qui a implémenté le routeur d'interface utilisateur et utilise ui-sref-active="active" pour ajouter la classe active à l'élément de menu de navigation lorsque cet élément correspond à l'itinéraire actuel. Toutefois, lorsque vous accédez à une vue imbriquée dans cette vue, l'élément de menu parent n'est plus actif. Voir le Plunker suivant:

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

Par défaut (ou si vous cliquez dessus), Route 1 est "active". Lorsque vous cliquez sur "Afficher la liste", vous verrez que la Route 1 n'est plus active.

Modifier:

La seule différence entre cet exemple et mon projet actuel est que le menu de navigation de mon projet actuel possède son propre contrôleur et n'utilise donc pas la même étendue que le contrôleur pour "route1".

19
Ian Walter

EDIT Pour le routeur ui mis à jour 0.2.13:

ui-sref-active="active" définit maintenant la classe 'active' lorsque l'état actuel est l'état de ui-sref ou de n'importe quel enfant

ui-sref-active-eq="active" se comporte comme les itérations précédentes de ui-sref-active et ne définit que la classe pour l'état exact

Réponse originale:

Voir les problèmes relatifs au routeur ui: https://github.com/angular-ui/ui-router/issues/704 et 818

Une solution de contournement générale suggérée par les utilisateurs est la suivante:

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

Bien sûr, $ state doit être ajouté à $ scope. Voir le dossier mis à jour: http://plnkr.co/edit/KHLDJP?p=preview

60
Chris T

Vous avez une mauvaise compréhension de ui-sref-active = "active"

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

Cela mettra en évidence les CSS spéciales uniquement lorsque vous êtes dans l'état route1 (référence https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active ). C'est le cas lorsque vous cliquez sur la route 1. Mais lorsque vous cliquez sur "Afficher la liste", vous n'êtes plus dans route1 . Vous êtes plutôt dans l'état "route1.list". Vous pouvez le vérifier en écrivant le code suivant. Ceci est strictement pour comprendre comment fonctionne l'état.

js

contrôleur intérieur

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

à l'intérieur html

{{currentState}}

Si vous examinez attentivement la documentation de ui-sref-active, celle-ci s'intéresse non seulement à stateName, mais également à stateParams. Par conséquent, lorsque vous passez au sous-état, il ne change plus les données CSS. À partir du code source, cela devient plus clair.

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

pour résoudre le problème, rappelez-vous que les variables de portée sont héritées dans des vues imbriquées.

contrôleur intérieur de route.

$scope.route1Active = true;

en html

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

Le routeur d'interface utilisateur angulaire le prend maintenant en charge de manière native. Voir commit https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

5
Kenneth Lynne

Ma solution était de définir:

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

L'état était déjà précédemment ajouté à la portée du contrôleur: 

$scope.state = $state;
4
Ian Walter

Maintenant, ils ont mis à jour et la nouvelle façon de le faire est

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

Ci-dessous le fichier d'état

 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'
          }
        }
      });
2
Siddharth Pandey

Vous n'avez rien à faire dans les contrôleurs. Voici mon exemple de code:

    <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>

En configuration de route:

$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"
            }
        }
    });
2
Yang Zhang

Je suis venu ici 2 ans plus tard, la question a été posée mais angular-ui-router a une approche beaucoup plus compétente pour résoudre ce problème. Cela a également fonctionné pour les États imbriqués.

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

Lorsque l'application navigue vers l'état home, voici comment le résultat HTML apparaîtra:

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

référence rapide ui-sref-active:

Une directive travaillant aux côtés de ui-sref pour ajouter des classes à un élément lorsque l'état de la directive ui-sref associée est actif et en supprimant eux quand il est inactif. Le principal cas d'utilisation consiste à simplifier le fichier apparence spéciale des menus de navigation reposant sur ui-sref, en ayant le bouton de menu de l'état "actif" apparaît différemment, ce qui le distingue des éléments de menu inactifs.

Documentation complète.

1
BeingSuman

J'espère que c'est ce que vous recherchiez.Placez l'URL du parent dans la classe list, à présent chaque fois que vous naviguerez dans la classe enfant

Étape 1: Ajoutez un contrôleur pour votre barre de navigation ou dans votre contrôleur existant où la barre de navigation est incluse, ajoutez ce qui suit

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

}]);

Étape 2: dans votre barre de navigation

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

C'est tout.

0
user6664928