145

次のように AngularJS にルートを設定しています。

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

トップバーにタブのスタイルのリンクがいくつかあります。現在のテンプレートまたは URL に応じて「アクティブな」クラスをタブに追加するにはどうすればよいですか?

4

18 に答える 18

275

URL に依存せずにこれを解決する方法は$routeProvider、次のように、構成中にすべてのパーシャルにカスタム属性を追加することです。

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

コントローラーで公開$routeします。

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

active現在アクティブなタブに基づいてクラスを設定します。

<li ng-class="{active: $route.current.activetab == 'dashboard'}"></li>
<li ng-class="{active: $route.current.activetab == 'lab'}"></li>
于 2012-09-25T15:28:18.180 に答える
134

これを行う1つの方法は、ngClassディレクティブと$locationサービスを使用することです。テンプレートでは、次のことができます。

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

ここisActiveで、次のように定義されたスコープ内の関数は次のようになります。

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

完全なjsFiddleは次のとおりです。http://jsfiddle.net/pkozlowski_opensource/KzAfG/

各ナビゲーションタブで繰り返すng-class="{active:isActive('/dashboard')}"のは面倒な場合があるため(タブが多数ある場合)、このロジックは非常に単純なディレクティブの候補になる可能性があります。

于 2012-09-06T18:23:31.953 に答える
27

@rob-juurlink私はあなたのソリューションを少し改善しました:

アクティブなタブを必要とする各ルートの代わりに。各コントローラーでアクティブなタブを設定する必要があるため、次のようにします。

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;
   });
}]);

そして、HTMLは次のようになります。activetab は、そのルートに関連する URL です。これにより、各コントローラーにコードを追加する必要がなくなります (これが使用される唯一の理由である場合は、$route や $rootScope などの依存関係をドラッグします)。

<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>
于 2013-03-27T12:09:56.723 に答える
16

おそらく、このようなディレクティブが問題を解決するかもしれません: 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);
                }
            });
        }

    };

}]);
于 2012-09-27T22:53:08.083 に答える
12

I recommend using the state.ui module which not only support multiple and nested views but also make this kind of work very easy (code below quoted) :

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

Worth reading.

于 2013-08-01T00:39:10.007 に答える
3

私は、XMLilley の anwser が最良で、最も適応性が高く、邪魔にならないことを発見しました。

ただし、小さな不具合がありました。

ブートストラップ ナビで使用するために、次のように変更しました。

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");
                }
            }
        });
      }
    };
  });

「if(attrs.href!=undefined)」を追加したのは、この関数が明らかに 2 回呼び出され、2 回目にエラーが発生したためです。

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>
于 2013-08-15T13:09:52.017 に答える
3

ブートストラップの例。

ルーティング (ngview) に組み込まれた Angulars を使用している場合、このディレクティブを使用できます。

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);
                }
            });

        }
    };
}]);

マークアップが次のようになっていると仮定します。

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

属性に必要なクラス名を設定できるので、これが好きです。

于 2014-11-23T09:59:48.373 に答える
2

また、場所をスコープに単純に挿入し、それを使用してナビゲーションのスタイルを差し引くこともできます。

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

次に、あなたの中でそれを使用してくださいng-class

<li ng-class="{active: location.path() == '/search'}">
  <a href="/search">Search><a/>
</li>
于 2013-02-01T14:50:23.580 に答える
2

別の方法は、ui-sref-activeを使用することです

関連する ui-sref ディレクティブの状態がアクティブなときに要素にクラスを追加し、非アクティブなときにそれらを削除するために ui-sref と一緒に機能するディレクティブ。主な使用例は、ui-sref に依存するナビゲーション メニューの特別な外観を単純化することです。これは、「アクティブ」状態のメニュー ボタンを非アクティブなメニュー項目と区別して異なるように見せることによって行います。

使用法:

ui-sref-active='class1 class2 class3' - クラス「class1」、「class2」、および「class3」は、関連する ui-sref の状態がアクティブなときにディレクティブ要素にそれぞれ追加され、非アクティブなときに削除されます。

例:
次のテンプレートの場合、

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

アプリの状態が「app.user」で、値が「bilbobaggins」の状態パラメーター「user」が含まれている場合、結果の HTML は次のように表示されます。

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

クラス名は、ディレクティブのリンク時に 1 回補間されます (補間された値に対するそれ以降の変更は無視されます)。複数のクラスをスペース区切り形式で指定できます。

オプションを $state.go() に渡すには、ui-sref-opts ディレクティブを使用します。例:

<a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
于 2016-02-01T13:57:02.457 に答える
1

コントローラにカスタム属性を設定することについてのRobの投稿に同意します。どうやら私はコメントするのに十分な担当者がいません。リクエストされたjsfiddleは次のとおりです。

サンプル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>

サンプル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/

于 2013-03-13T21:18:24.657 に答える
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();
    };
  });

テンプレートで以下を使用します。

<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>
于 2015-06-03T23:04:21.797 に答える
0

この方法をどこで見つけたか思い出せませんが、非常にシンプルでうまく機能します。

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;
  } 
于 2016-04-12T14:20:34.710 に答える
-3

解決策のためにここに来ました..上記の解決策は正常に機能していますが、少し複雑で不要であることがわかりました。簡単できちんとしたソリューションをまだ探している人にとっては、それはタスクを完全に実行します.

<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>
于 2015-07-19T12:04:04.567 に答える