Angular JSでブートストラップnavbarアクティブクラスを設定するにはどうすればよいですか?


306

アイテムのブートストラップにナビゲーションバーがある場合

Home | About | Contact

各メニュー項目がアクティブなときに、それらのアクティブクラスをどのように設定しますか?つまりclass="active"、角度ルートが

  1. #/ 家のために
  2. #/about アバウトページについて
  3. #/contact お問い合わせページ


10
これは似ていますが、ナビゲーションボタンを強調表示する「角度のある方法」ではありません。
user1876508 2013年


Angularルーティングを使用している場合は、完全な答えがスタックオーバーフローの下に埋もれていることに注意してください:stackoverflow.com/a/43822400/474189
ダンカンジョーンズ

回答:


598

非常にエレガントな方法は、ng-controllerを使用して、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>

そしてcontrollers.jsに含めます:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}

10
これは初めてなので、これをヘッダーディレクティブに入れる方法の例を提供していただければ幸いです。
mono68、2013

41
return $location.path().indexOf(viewLocation) == 0;パラメータを使用してページをキャッチできるように、代わりに使用することをお勧めします
Sven Hecht 2014

7
これで作業は完了しますが、ほとんどできません。elegantたとえば/dogs、次の呼び出しでルート名を複製する必要がありますisActive('/dogs')
wal

7
UIルーターを使用している場合は、ui-sref-active/ui-sref-active-eqディレクティブを使用できます。ui-sref-active-eq='active'またはui-sref-active='active'同じ結果を達成するには
Dan Pantry 2015

10
@SvenHechtこのロジックの問題は、ホームページのリンク(/)が他のすべてのパスと一致することです。
mwotton 2015

51

これを処理するディレクティブを作成したので、属性bs-active-linkを親<ul>要素に追加するだけで、ルートが変更されるたびに、一致するリンクが見つかり、対応するにactiveクラスが追加され<li>ます。

あなたはここでそれを実際に見ることができます:http : //jsfiddle.net/8mcedv3b/

HTMLの例:

<ul class="nav navbar-nav" bs-active-link>
  <li><a href="/home">Home</a></li>
  <li><a href="/contact">Contact</a></li>
</ul>

JavaScript:

angular.module('appName')
.directive('bsActiveLink', ['$location', function ($location) {
return {
    restrict: 'A', //use as attribute 
    replace: false,
    link: function (scope, elem) {
        //after the route has changed
        scope.$on("$routeChangeSuccess", function () {
            var hrefs = ['/#' + $location.path(),
                         '#' + $location.path(), //html5: false
                         $location.path()]; //html5: true
            angular.forEach(elem.find('a'), function (a) {
                a = angular.element(a);
                if (-1 !== hrefs.indexOf(a.attr('href'))) {
                    a.parent().addClass('active');
                } else {
                    a.parent().removeClass('active');   
                };
            });     
        });
    }
}
}]);

1
私より良い受け入れ答えよりも、この設定データのない重複がありませんので、すなわち自体はただ一つの場所にとどまるルートやこれだけの作品..のような
アーロンAnodide

1
scope。$ on( "$ routeChangeSuccess"、function(){....の代わりにscope。$ watch( "$ routeChangeSuccess"、function(){....を使用して私のために働きました
aemad

私自身の目的のためにこれを少し調整する必要がありましたが、素晴らしい答えです!理解するのに十分簡単です。
Tony Anziano 2016年

38

あなたはAngularStrapを見ることができます、navbarディレクティブはあなたが探しているもののようです:

https://github.com/mgcrea/angular-strap/blob/master/src/navbar/navbar.js

.directive('bsNavbar', function($location) {
  'use strict';

  return {
    restrict: 'A',
    link: function postLink(scope, element, attrs, controller) {
      // Watch for the $location
      scope.$watch(function() {
        return $location.path();
      }, function(newValue, oldValue) {

        $('li[data-match-route]', element).each(function(k, li) {
          var $li = angular.element(li),
            // data('match-rout') does not work with dynamic attributes
            pattern = $li.attr('data-match-route'),
            regexp = new RegExp('^' + pattern + '$', ['i']);

          if(regexp.test(newValue)) {
            $li.addClass('active');
          } else {
            $li.removeClass('active');
          }

        });
      });
    }
  };
});

このディレクティブを使用するには:

  1. AngularStrapをhttp://mgcrea.github.io/angular-strap/からダウンロードします

  2. スクリプトをbootstrap.jsの後にページに含めます。
    <script src="lib/angular-strap.js"></script>

  3. モジュールにディレクティブを追加します。
    angular.module('myApp', ['$strap.directives'])

  4. ディレクティブをナビゲーションバーに追加します。
    <div class="navbar" bs-navbar>

  5. 各ナビゲーションアイテムに正規表現を追加します。
    <li data-match-route="/about"><a href="#/about">About</a></li>


1
ありがとう。これは私自身のディレクティブを修正するのに役立ちました(私にとって欠けている洞察はでしたscope.$watch
Ngure Nyaga

element変数がjqueryセレクターに渡されるのはなぜですか?$('...', element)
Lucio 2014年

@Lucioメソッドは2つの引数を取ります-jQuery(selector、context)-2番目の引数は、セレクターのコンテキスト(親DOM要素または別のjQueryオブジェクト自体)を渡すことです-詳細はこちら
CoderTR

これは私にとっては完璧に機能します。ただし、1つの変更を行う必要がありました。 に機能します-1を加える必要がありまし mgcrea.github.io angularmgcrea.ngStrap$strap.directives
strapで

33

これは、Angularでうまく機能する簡単なアプローチです。

<ul class="nav navbar-nav">
    <li ng-class="{ active: isActive('/View1') }"><a href="#/View1">View 1</a></li>
    <li ng-class="{ active: isActive('/View2') }"><a href="#/View2">View 2</a></li>
    <li ng-class="{ active: isActive('/View3') }"><a href="#/View3">View 3</a></li>
</ul>

AngularJSコントローラー内:

$scope.isActive = function (viewLocation) {
     var active = (viewLocation === $location.path());
     return active;
};

2
素敵なアプローチ。少し変更しました-ng-classディレクティブ(ng-class = {active:isActive( '/ View1')})を使用し、isActive関数を更新して、クラス名自体ではなくtrue / falseを返しました。
patelsan 2013

私はあなたの例のようにすべてをコピーしました、そして私にとって$ location.path()はうまくいきませんでした... $ location.url()に切り替えて、それはうまくいきました!
Paulo Oliveira

14

Angularルーターを使用している場合は、RouterLinkActiveディレクティブを非常にエレガントに使用できます。

<ul class="navbar-nav">
  <li class="nav-item"><a class="nav-link" routerLink="home" routerLinkActive="active">Home</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="gallery" routerLinkActive="active">Gallery</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="pricing" routerLinkActive="active">Prices</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="contact" routerLinkActive="active">Contact</a></li>
</ul>

2
これは受け入れられる答えであると思います(少なくとも角度2+の場合)。ただし、Bootstrap 3.3の場合、activeクラスは<li>(routerLinkActiveをrouterLinkまたはその親と一緒に配置できます)にある必要があります
PhoneixS

3
注:あなたが使用している場合は/、あなたのホームページとして、routerLinkActiveで始まるURLのためにそのアクティブを検討する/、例えば/foo//foo/bar完全に一致するなど、あなたが必要としますrouterLinkActive="active" [routerLinkActiveOptions]="{exact:true}"
Duncan Jones、

8

何よりもまず、この問題はさまざまな方法で解決できます。この方法は最もエレガントではないかもしれませんが、確実に機能します。

以下は、どのプロジェクトにも追加できる簡単なソリューションです。キーをオフにするために使用できるルートを構成するときに、「pageKey」またはその他のプロパティを追加できます。さらに、$ routeオブジェクトの$ routeChangeSuccessメソッドにリスナーを実装して、ルート変更の正常な完了をリッスンできます。

ハンドラーが起動すると、ページキーを取得し、そのキーを使用して、このページで "ACTIVE"である必要がある要素を見つけ、ACTIVEクラスを適用します。

すべての要素を「アクティブ」にする方法が必要であることを覚えておいてください。ご覧のとおり、ナビゲーションアイテムで.pageKeyクラスを使用してそれらをすべてオフにし、.pageKey_ {PAGEKEY}を使用して個別にオンにしています。それらをすべて非アクティブに切り替えると、単純なアプローチと見なされます。以前のルートを使用してアクティブアイテムのみを非アクティブにすると、パフォーマンスが向上する可能性があります。または、jqueryセレクターを変更して、非アクティブにするアクティブアイテムのみを選択することもできます。jqueryを使用してすべてのアクティブな項目を選択することは、前のルートに存在する可能性のあるcssバグが発生した場合に、現在のルートのすべてがクリーンアップされるため、おそらく最良のソリューションです。

つまり、次のコード行を変更することになります。

$(".pagekey").toggleClass("active", false);

これに

$(".active").toggleClass("active", false);

ここにいくつかのサンプルコードがあります:

のブートストラップnavbarを考えると

<div class="navbar navbar-inverse">
    <div class="navbar-inner">
        <a class="brand" href="#">Title</a>
        <ul class="nav">
            <li><a href="#!/" class="pagekey pagekey_HOME">Home</a></li>
            <li><a href="#!/page1/create" class="pagekey pagekey_CREATE">Page 1 Create</a></li>
            <li><a href="#!/page1/edit/1" class="pagekey pagekey_EDIT">Page 1 Edit</a></li>
            <li><a href="#!/page1/published/1" class="pagekey pagekey_PUBLISH">Page 1 Published</a></li>
        </ul>
    </div>
</div>

そして次のような角度モジュールとコントローラー:

<script type="text/javascript">

    function Ctrl($scope, $http, $routeParams, $location, $route) {

    }



    angular.module('BookingFormBuilder', []).
        config(function ($routeProvider, $locationProvider) {
            $routeProvider.
                when('/', { 
                   template: 'I\'m on the home page', 
                   controller: Ctrl, 
                   pageKey: 'HOME' }).
                when('/page1/create', { 
                   template: 'I\'m on page 1 create', 
                   controller: Ctrl, 
                   pageKey: 'CREATE' }).
                when('/page1/edit/:id', { 
                   template: 'I\'m on page 1 edit {id}', 
                   controller: Ctrl, pageKey: 'EDIT' }).
                when('/page1/published/:id', { 
                   template: 'I\'m on page 1 publish {id}', 
                   controller: Ctrl, pageKey: 'PUBLISH' }).
                otherwise({ redirectTo: '/' });

            $locationProvider.hashPrefix("!");
        }).run(function ($rootScope, $http, $route) {

            $rootScope.$on("$routeChangeSuccess", 
                           function (angularEvent, 
                                     currentRoute,
                                     previousRoute) {

                var pageKey = currentRoute.pageKey;
                $(".pagekey").toggleClass("active", false);
                $(".pagekey_" + pageKey).toggleClass("active", true);
            });

        });

</script>

ルートのpageKey値を表示するには、右にスクロールする必要があります。これが、このソリューション全体の鍵です。
Mark At Ramp51 2013

16
これは機能するかもしれませんが、Angular.jsアプリに対する一般的なアドバイスに反しています。Angularでは、jQueryを使用してDOMをいじることを控える必要があります。DOMに触れる必要がある場合は、ディレクティブを記述します。
Paulo Scardine 2013年

これは完璧です。dom操作が気になる場合は、.navbarにディレクティブを追加し、$ broadcastイベントをroutechangesuccessに追加します。$ rootScope。$ broadcast( 'routeChanged'、current.pageKey); そしてそれをあなたの指令で捕らえ、そこでdom操作を行ってください
Irshu

7

angular-ui-utils ' ui-routeディレクティブを実際に使用できます:

<a ui-route ng-href="/">Home</a>
<a ui-route ng-href="/about">About</a>
<a ui-route ng-href="/contact">Contact</a>

または:

ヘッダーコントローラー

/**
 * Header controller
 */
angular.module('myApp')
  .controller('HeaderCtrl', function ($scope) {
    $scope.menuItems = [
      {
        name: 'Home',
        url:  '/',
        title: 'Go to homepage.'
      },
      {
        name:   'About',
        url:    '/about',
        title:  'Learn about the project.'
      },
      {
        name:   'Contact',
        url:    '/contact',
        title:  'Contact us.'
      }
    ];
  });

索引ページ

<!-- index.html: -->
<div class="header" ng-controller="HeaderCtrl">
  <ul class="nav navbar-nav navbar-right">
    <li ui-route="{{menuItem.url}}" ng-class="{active: $uiRoute}"
      ng-repeat="menuItem in menuItems">
      <a ng-href="#{{menuItem.url}}" title="{{menuItem.title}}">
        {{menuItem.name}}
      </a>
    </li>
  </ul>
</div>

ui-utilsを使用している場合は、部分的/ネストされたビューを管理するためのui-routerにも興味があるかもしれません。


ui-routeアプローチは非常に魅力的ですが、これまでのところ、Yeomanの角度ジェネレーターによって生成されたプロジェクトで動作させることができませんでした。
gabuzo 2014

@gabuzo:Bower経由でangular-ui-utilsをインストールしましたか?
Lèseはmajesté

6

申し訳ありませんが、これらの答えはすべて少し複雑になっています。だから私はnavbarごとに機能する小さなディレクティブを作成しました:

app.directive('activeLink', function () {
    return {
        link: function (scope, element, attrs) {
            element.find('.nav a').on('click', function () {
                angular.element(this)
                    .parent().siblings('.active')
                    .removeClass('active');
                angular.element(this)
                    .parent()
                    .addClass('active');
            });
        }
    };
});

使用法:

<ul class="nav navbar-nav navbar-right" active-link>
    <li class="nav active"><a href="home">Home</a></li>
    <li class="nav"><a href="foo">Foo</a></li>
    <li class="nav"><a href="bar">Bar</a></li>
</ul>

この方法は、ナビゲーションバーのリンクをクリックした後にのみ機能します。「Foo」のURLから開始すると、最初はまだ「ホーム」が選択されています。たとえば、localhost:9000 /#/ contactで開始すると、ホームがナビゲーションバーで選択された状態で表示されます。
Adam Plocher、2016年

5

私はそれを達成するために$ locationでng-classディレクティブを使用します。

<ul class="nav">
<li data-ng-class="{active: ($location.path() == '/') }">
    <a href="#/">Carpeta Amarilla</a>
</li>
<li class="dropdown" data-ng-class="{active: ($location.path() == '/auditoria' || $location.path() == '/auditoria/todos') }">
    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
        Auditoria
        <b class="caret"></b>
    </a>
    <ul class="dropdown-menu pull-right">
        <li data-ng-class="{active: ($location.path() == '/auditoria') }">
            <a href="#/auditoria">Por Legajo</a>
        </li>
        <li data-ng-class="{active: ($location.path() == '/auditoria/todos') }">
            <a href="#/auditoria/todos">General</a>
        </li>
    </ul>
</li>
</ul>

ナビゲーションバーは、次のように$ locationサービスにアクセスできるメインコントローラー内にある必要があります。

bajasApp.controller('MenuCntl', ['$scope','$route', '$routeParams', '$location', 
   function MenuCntl($scope, $route, $routeParams, $location) {
   $scope.$route = $route;
   $scope.$location = $location;
   $scope.$routeParams = $routeParams;
}]);

4

次のような角度式の条件付きでこれを実現できます。

<a href="#" class="{{ condition ? 'active' : '' }}">link</a>

そうは言っても、このミニロジックの多くをアウトソーシングするとコードベースがいくらか汚染される可能性がありますが、角度のディレクティブはより適切な方法であることがわかります。

ディレクティブを作成するよりも少し速いので、開発中は時々GUIスタイリングに条件文を使用します。実際にはコードベースに長く留まっている例はわかりませんでした。最後に、それをディレクティブに変えるか、問題を解決するためのより良い方法を見つけます。


4

ui-routerを使用する場合、次の例は、コントローラー側のコードを追加せずに、@ DanPantryの承認された回答に関するコメントに基づいてニーズを満たします。

<div class="collapse navbar-collapse" ng-controller="HeaderController">
    <ul class="nav navbar-nav">
        <li ui-sref-active="active"><a ui-sref="app.home()" href="/">Home</a></li>
        <li ui-sref-active="active"><a ui-sref="app.dogs()" href="/dogs">Dogs</a></li>
        <li ui-sref-active="active"><a ui-sref="app.cats()" href="/cats">Cats</a></li>
    </ul>
</div>
<div ng-view></div>

詳細については、ドキュメントを確認してください。


パーフェクト!確かに最もクリーンなソリューション
Aryeh Beitz

非常に単純に最善の解決策です。使っていない人ui.router
dewd

3

AngularStrapを使用したくない場合は、このディレクティブでうまくいくはずです!。これはhttps://stackoverflow.com/a/16231859/910764の変更です。

JavaScript

angular.module('myApp').directive('bsNavbar', ['$location', function ($location) {
  return {
    restrict: 'A',
    link: function postLink(scope, element) {
      scope.$watch(function () {
        return $location.path();
      }, function (path) {
        angular.forEach(element.children(), (function (li) {
          var $li = angular.element(li),
            regex = new RegExp('^' + $li.attr('data-match-route') + '$', 'i'),
            isActive = regex.test(path);
          $li.toggleClass('active', isActive);
        }));
      });
    }
  };
}]);

HTML

<ul class="nav navbar-nav" bs-navbar>
  <li data-match-route="/home"><a href="#/home">Home</a></li>
  <li data-match-route="/about"><a href="#/about">About</a></li>
</ul>

注:上記のHTMLクラスは、Bootstrap 3.xを使用していることを前提としています。


3

私の考えはここにあります。この投稿で見つかった回答の組み合わせの一部。私は少し異なるケースがあったので、私の解決策は、メニューを独自のテンプレートに分離してディレクティブ定義オブジェクト内で使用し、次にナビゲーションバーを必要なページに追加することです。基本的に、メニューを含めたくないログインページがあったので、ngIncludeを使用して、ログイン時にこのディレクティブを挿入しました。

指令:

module.directive('compModal', function(){


return {
    restrict: 'E',
    replace: true,
    transclude: true,
    scope: true,
    templateUrl: 'templates/menu.html',
    controller: function($scope, $element, $location){
        $scope.isActive = function(viewLocation){

            var active = false;

            if(viewLocation === $location.path()){
                active = true;
            }

            return active;

        }
    }
 }
});

ディレクティブテンプレート(templates / menu.html)

<ul class="nav navbar-nav">
  <li ng-class="{ active: isActive('/View1') }"><a href="#/View1">View 1</a></li>
  <li ng-class="{ active: isActive('/View2') }"><a href="#/View2">View 2</a></li>
  <li ng-class="{ active: isActive('/View3') }"><a href="#/View3">View 3</a></li>
</ul>

指令を含むHTML

<comp-navbar/>

お役に立てれば


1
関数は$ scope.isActive = function(viewLocation){return viewLocation === $ location.path();に短縮できます。};
WP McNeill

2

mylの回答を拡張して、このような構造を処理するためにこれが必要でした。

-index

-events <-active
--- event-list
--- event-edit
--- event-map <-clicked

-places
--- place-list
--- place-edit
--- place-map

したがって、一致する代わりに、条件に一致するようにフォーマットされた子リンクを検証するために、indexOfを使用する必要がありました。したがって、「イベント」の場合:

<li ng-class="{ active: isActive('/event')}" class="divider-vertical dropdown">


function NavController($scope, $location) { 
$scope.isActive = function (viewLocation) {
    var s=false;
    if($location.path().indexOf(viewLocation) != -1){
     s = true;
    }
    return s;
};}

2

これは簡単な解決策です

<ul class="nav navbar-nav navbar-right navbar-default menu">
  <li ng-class="menuIndice == 1 ? 'active':''">
    <a ng-click="menuIndice = 1" href="#/item1">item1</a>
  </li>
  <li ng-class="menuIndice == 2 ? 'active':''">
    <a ng-click="menuIndice = 2" href="#/item2">item2</a>
  </li>
  <li ng-class="menuIndice == 3 ? 'active':''">
    <a ng-click="menuIndice = 3" href="#/item3">item3</a>
  </li>
</ul>

1

@OlivierのAngularStrap回答と組み合わせて、https//github.com/twbs/bootstrap/issues/9013からのkevinknelsonの回答も実装しました。

本来、Bootstrap3 navbarは単一ページ(Angularなど)のアプリケーション用に設計されていなかったため、小さな画面のメニューがクリックしても折りたたまれませんでした。


1

JavaScript

/**
 * Main AngularJS Web Application
 */

var app = angular.module('yourWebApp', [
    'ngRoute'
]);


/**
 * Setup Main Menu
 */

app.controller('MainNavCtrl', [ '$scope', '$location', function ( $scope, $location) {
    $scope.menuItems = [
        {
            name: 'Home',
            url:  '/home',
            title: 'Welcome to our Website'
        },
        {
            name: 'ABOUT',
            url:  '/about',
            title: 'Know about our work culture'
        },
        {
            name:   'CONTACT',
            url:    '/contact',
            title:  'Get in touch with us'
        }
    ];

    $scope.isActive = function (viewLocation) {
        return viewLocation === $location.path();
    };
}]);

HTML

  <div class="navbar-collapse collapse" ng-controller="MainNavCtrl">
    <ul id="add-magic-line" class="nav navbar-nav navbar-right">
      <li data-ng-class="{current_page_item: isActive('{{ menuItem.url }}')}" data-ng-repeat="menuItem in menuItems">
        <a data-ng-href="#{{menuItem.url}}" title="{{menuItem.title}}">
          {{menuItem.name}}
        </a>
      </li>
    </ul>
  </div>

これは機能しません-現在のクラスをDOMに追加しません
TheBlackBenzKid

1

@Pylinuxに感謝します。私は彼のテクニックを使用し、「1」レベルのドロップダウンメニュー(サブul / li)をサポートするように変更しました。以下のフィドルリンクで実際の動作を確認してください。

pylinuxの回答に基づいてFiddleを更新-http : //jsfiddle.net/abhatia/en4qxw6g/

1つのレベルのドロップダウンメニューをサポートするために、次の3つの変更を
加えました。

         <li><a class="dd">This link points to #/fun5</a>
          <ul>
            <li><a href="#/fun6?some=data">This link points to #/fun6</a>
            </li>
            <li><a href="#/fun7?some=data">This link points to #/fun7</a>
            </li>
            <li><a href="#/fun8?some=data">This link points to #/fun8</a>
            </li>
            <li><a href="#/fun9?some=data">This link points to #/fun9</a>
            </li>
          </ul>
        </li>


2.次の新しいロジックを追加するようにJavaScriptを更新しました。

 if(angular.element(li).parent().parent().children('a').hasClass("dd"))
 {angular.element(li).parent().parent().children('a.dd').addClass('active');}


3. CSSを更新して以下を追加します。

a.active {background-color:red;}

うまくいけば、これは単一レベルのドロップダウンメニューを実装したい人に役立つでしょう。


1

オブジェクトをスイッチ変数として使用します。
あなたはこれを非常に簡単にインラインで行うことができます:

<ul class="nav navbar-nav">
   <li ng-class="{'active':switch.linkOne}" ng-click="switch = {linkOne: true}"><a href="/">Link One</a></li>
   <li ng-class="{'active':switch.linkTwo}" ng-click="switch = {link-two: true}"><a href="/link-two">Link Two</a></li>
</ul>

リンクをクリックするたびに、スイッチオブジェクトは新しいオブジェクトに置き換えられ、正しいスイッチオブジェクトプロパティのみがtrueになります。未定義のプロパティはfalseと評価されるため、それらに依存する要素にはアクティブクラスが割り当てられません。



0

リンクにディレクティブを使用することをお勧めします。 ここにがフィドルです。

しかし、まだ完璧ではありません。hashbangsに注意してください;)

ディレクティブのJavaScriptは次のとおりです。

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 not return including hashbang
        scope.location = location;
        scope.$watch('location.path()', function(newPath) {
          if (path === newPath) {
            element.addClass(clazz);
          } else {
            element.removeClass(clazz);
          }
        });
      }
    };
  }]);

そしてこれが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>

その後cssでスタイリング:

.active{ color:red; }

0

議論に2セントを追加するために、純粋な角度モジュール(jqueryなし)を作成しました。これは、データを含むハッシュURLでも機能します。(ig #/this/is/path?this=is&some=data

モジュールを依存関係として追加しauto-active、メニューの祖先の1つに追加するだけです。このような:

<ul auto-active>
    <li><a href="#/">main</a></li>
    <li><a href="#/first">first</a></li>
    <li><a href="#/second">second</a></li>
    <li><a href="#/third">third</a></li>
</ul>

そしてモジュールはこのようになります:

(function () {
    angular.module('autoActive', [])
        .directive('autoActive', ['$location', function ($location) {
        return {
            restrict: 'A',
            scope: false,
            link: function (scope, element) {
                function setActive() {
                    var path = $location.path();
                    if (path) {
                        angular.forEach(element.find('li'), function (li) {
                            var anchor = li.querySelector('a');
                            if (anchor.href.match('#' + path + '(?=\\?|$)')) {
                                angular.element(li).addClass('active');
                            } else {
                                angular.element(li).removeClass('active');
                            }
                        });
                    }
                }

                setActive();

                scope.$on('$locationChangeSuccess', setActive);
            }
        }
    }]);
}());

*(もちろん、ディレクティブ部分だけを使用できます)

**これは、空のハッシュのために動作しない(ことも価値が気付かだIG example.com/#またはちょうどexample.comそれは、少なくとも持っている必要があります)、example.com/#/または単にexample.com#/。しかし、これはngResourceなどで自動的に行われます。


それは単に厄介です。Angularを使用する理由は簡単にするためです。
トムスティッケル2015年

0

これは私のためのトリックをしました:

  var domain = '{{ DOMAIN }}'; // www.example.com or dev.example.com
  var domain_index =  window.location.href.indexOf(domain);
  var long_app_name = window.location.href.slice(domain_index+domain.length+1); 
  // this turns http://www.example.com/whatever/whatever to whatever/whatever
  app_name = long_app_name.slice(0, long_app_name.indexOf('/')); 
  //now you are left off with just the first whatever which is usually your app name

次に、jquery(angularでも機能します)を使用してアクティブなクラスを追加します

$('nav a[href*="' + app_name+'"]').closest('li').addClass('active');

そしてもちろんCSS:

.active{background:red;}

これは、次のようなHTMLがある場合に機能します。

<ul><li><a href="/ee">ee</a></li><li><a href="/dd">dd</a></li></ul>

これにより、ページのURLを使用してアクティブなクラスが自動的に追加され、www.somesite.com / eeのthaen eeが「アプリ」でアクティブな場合、背景が赤に色付けされます。


0

これは長い間答えられましたが、私は自分のやり方を共有したいと思いました:

.run(function($rootScope, $state){
 $rootScope.$state = $state;
});

テンプレート:

<ul class="nav navbar-nav">
    <li ng-class="{ active: $state.contains('View1') }"><a href="...">View 1</a></li>
    <li ng-class="{ active: $state.contains('View2') }"><a href="...">View 2</a></li>
    <li ng-class="{ active: $state.contains('View3') }"><a href="...">View 3</a></li>
</ul>

を使用している場合ui-router

<ul class="nav navbar-nav">
        <li ui-sref-active="active"><a href="...">View 1</a></li>
        <li ui-sref-active="active"><a href="...">View 2</a></li>
        <li ui-sref-active="active"><a href="...">View 3</a></li>
</ul>

完全に一致する場合(例:ネストされた状態?)$state.name === 'full/path/to/state'またはui-sref-active-eq="active"


0

興味があるかもしれない人のための別の解決策があります。これの利点は、依存関係が少ないことです。一体、それはウェブサーバーなしでも動作します。つまり、完全にクライアント側です。

HTML:

<nav class="navbar navbar-inverse" ng-controller="topNavBarCtrl"">
<div class="container-fluid">
    <div class="navbar-header">
        <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-home" aria-hidden="true"></span></a>
    </div>
    <ul class="nav navbar-nav">
        <li ng-click="selectTab()" ng-class="getTabClass()"><a href="#">Home</a></li>
        <li ng-repeat="tab in tabs" ng-click="selectTab(tab)" ng-class="getTabClass(tab)"><a href="#">{{ tab }}</a></li>
    </ul>
</div>

説明:

ここでは、ディレクティブを使用してangularjsモデルから動的にリンクを生成していますng-repeat。魔法の方法で発生selectTab()し、getTabClass()以下に示すこのナビゲーションバーのためのコントローラで定義されました。

コントローラ:

angular.module("app.NavigationControllersModule", [])

// Constant named 'activeTab' holding the value 'active'. We will use this to set the class name of the <li> element that is selected.
.constant("activeTab", "active")

.controller("topNavBarCtrl", function($scope, activeTab){
    // Model used for the ng-repeat directive in the template.
    $scope.tabs = ["Page 1", "Page 2", "Page 3"];

    var selectedTab = null;

    // Sets the selectedTab.
    $scope.selectTab = function(newTab){
       selectedTab = newTab;
    };

    // Sets class of the selectedTab to 'active'.
    $scope.getTabClass = function(tab){
       return selectedTab == tab ? activeTab : "";
    };
});

説明:

selectTab()メソッドはng-clickディレクティブを使用して呼び出されます。したがって、リンクをクリックすると、変数selectedTabはこのリンクの名前に設定されます。HTMLでは、このメソッドが[ホーム]タブの引数なしで呼び出され、ページが読み込まれたときに強調表示されることがわかります。

このgetTabClass()メソッドはng-class、HTMLのディレクティブを介して呼び出されます。このメソッドは、そのタブがselectedTab変数の値と同じかどうかを確認します。trueの場合は「アクティブ」を返し、そうでない場合はng-classディレクティブによってクラス名として適用される「」を返します。次に、クラスに適用したcssはすべてactive、選択したタブに適用されます。


他の方法で別のタブに移動するとどうなりますか?
Miguel Carvajal

どういう意味ですか?
kovac 2016年

たとえば、他のタブ内にある別のページに移動するページ内のリンク。理にかなっていますか?
Miguel Carvajal

その場合、上記の回答でMuli Yulzaryが提案したように、ui-routerを使用する方が良いと思います。ui-routerは各URLに状態を割り当てます。したがって、誰かがリンクをクリックすると、ユーザーはそのリンクにルーティングされ、Angleアプリの状態が更新されます。次に、ui-sref = "active"はタブを強調表示します。これがangular 2のドキュメントです:ui-router.github.io/ng2。また、通常のブートストラップを使用する代わりに、Angularアプリで使用するために行われたUIブートストラップを確認してください。UIブートストラップ:angular-ui.github.io/bootstrap
Kovacの

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.