Bagaimana cara mengatur kelas aktif bootstrap navbar dengan Angular JS?

306

Jika saya memiliki navbar di bootstrap dengan item

Home | About | Contact

Bagaimana cara mengatur kelas aktif untuk setiap item menu ketika mereka aktif? Yaitu, bagaimana saya bisa mengatur class="active"ketika rute sudut berada di

  1. #/ untuk rumah
  2. #/about untuk halaman tentang
  3. #/contact untuk halaman kontak
pengguna1876508
sumber
kemungkinan duplikat dari tautan Buat Twitter Bootstrap navbar aktif
givanse
10
Ini serupa, tetapi bukan "cara sudut" untuk menyorot tombol navigasi.
user1876508
Kemungkinan duplikat dari set style tab aktif dengan AngularJS
Amit G
Jika Anda menggunakan perutean sudut , harap dicatat bahwa jawaban sempurna terkubur di bawah: stackoverflow.com/a/43822400/474189 .
Duncan Jones

Jawaban:

598

Cara yang sangat elegan adalah dengan menggunakan ng-controller untuk menjalankan satu kontroler di luar tampilan-ng:

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

dan sertakan di controllers.js:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}
myl
sumber
10
Karena saya baru dalam hal ini, saya akan sangat menghargai jika Anda dapat memberikan contoh tentang cara memasukkan ini ke dalam sebuah header header, tolong.
mono68
41
Saya sarankan menggunakan return $location.path().indexOf(viewLocation) == 0;sebagai gantinya sehingga Anda dapat menangkap halaman dengan parameter juga
Sven Hecht
7
Ini menyelesaikan pekerjaan tetapi hampir tidak elegant- nama rute misalnya /dogsharus diduplikasi dalam panggilan keisActive('/dogs')
wal
7
Jika Anda menggunakan Router UI, maka Anda dapat menggunakan ui-sref-active/ui-sref-active-eqarahan, yaitu. ui-sref-active-eq='active'atau ui-sref-active='active'untuk mencapai hasil yang sama
Dan Pantry
10
@SvenHecht Kekhawatiran dengan logika itu adalah bahwa tautan beranda (/) akan cocok dengan setiap jalur lainnya.
mwotton
51

Saya baru saja menulis arahan untuk menangani hal ini, jadi Anda bisa menambahkan atribut bs-active-linkke <ul>elemen induk , dan setiap kali rute diubah, ia akan menemukan tautan yang cocok, dan menambahkan activekelas ke yang sesuai <li>.

Anda dapat melihatnya beraksi di sini: http://jsfiddle.net/8mcedv3b/

Contoh 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');   
                };
            });     
        });
    }
}
}]);
dave
sumber
1
saya suka ini lebih baik daripada jawaban yang diterima karena tidak ada duplikasi data konfigurasi, yaitu rute itu sendiri tetap di satu tempat dan ini hanya berfungsi ..
Aaron Anodide
1
bekerja untuk saya menggunakan scope. $ watch ("$ routeChangeSuccess", function () {.... bukannya scope. $ on ("$ routeChangeSuccess", function () {....
aemad
Harus men-tweak ini sedikit untuk keperluan saya sendiri, tetapi jawaban yang luar biasa! Cukup mudah dimengerti.
Tony Anziano
38

Anda dapat melihat di AngularStrap , arahan navbar tampaknya adalah yang Anda cari:

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

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

Untuk menggunakan arahan ini:

  1. Unduh AngularStrap dari http://mgcrea.github.io/angular-strap/

  2. Sertakan skrip di halaman Anda setelah bootstrap.js:
    <script src="lib/angular-strap.js"></script>

  3. Tambahkan arahan ke modul Anda:
    angular.module('myApp', ['$strap.directives'])

  4. Tambahkan arahan ke navbar Anda:
    <div class="navbar" bs-navbar>

  5. Tambahkan regex pada setiap item nav:
    <li data-match-route="/about"><a href="#/about">About</a></li>

Olivier
sumber
1
Terima kasih. Ini membantu saya memperbaiki arahan saya sendiri (wawasan yang hilang bagi saya adalah scope.$watch)
Ngure Nyaga
Mengapa elementvariabel diteruskan ke pemilih jquery? $('...', element)
Lucio
@Lucio metode mengambil 2 argumen - jQuery (pemilih, konteks) - argumen kedua adalah untuk melewati konteks pemilih, baik elemen DOM induk atau objek jQuery lain sendiri - baca selengkapnya di sini
CoderTR
Ini berfungsi dengan baik bagi saya - saya harus melakukan satu perubahan, namun per mgcrea.github.io/angular-strap arahan untuk menambahkan ke modul Anda mgcrea.ngStraptidak$strap.directives
Vixxd
33

Inilah pendekatan sederhana yang bekerja dengan baik dengan 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>

Di dalam pengontrol AngularJS Anda:

$scope.isActive = function (viewLocation) {
     var active = (viewLocation === $location.path());
     return active;
};
Ender2050
sumber
2
Pendekatan yang bagus. Saya memodifikasinya sedikit - menggunakan arahan kelas-ng (kelas-ng = {active: isActive ('/ View1')}) dan memperbarui fungsi isActive untuk mengembalikan true / false alih-alih nama kelas itu sendiri.
patelsan
Saya telah menyalin semua seperti contoh Anda, dan bagi saya $ location.path () tidak berfungsi ... beralih ke $ location.url (), dan berhasil!
Paulo Oliveira
14

Jika Anda bekerja dengan router Angular, direktif RouterLinkActive dapat digunakan dengan sangat elegan:

<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>
DVarga
sumber
2
Saya pikir ini harus menjadi jawaban yang diterima (setidaknya untuk sudut 2+), mengapa mengimplementasikan sesuatu sudah diterapkan? Tetapi untuk Bootstrap 3.3 activekelasnya harus di <li>(Anda dapat menempatkan routerLinkActive dengan routerLink atau induknya)
PhoneixS
3
Catatan: jika Anda menggunakannya /sebagai beranda, Anda routerLinkActiveakan menganggapnya aktif untuk URL apa pun yang dimulai dengan /, misalnya /foo/, /foo/bardll. Untuk mencocokkan dengan tepat, Anda perlu routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}".
Duncan Jones
8

Pertama dan terpenting, masalah ini dapat dipecahkan dengan banyak cara. Cara ini mungkin bukan yang paling elegan, tapi itu bekerja dengan baik.

Berikut adalah solusi sederhana yang harus Anda tambahkan ke proyek apa pun. Anda bisa menambahkan "pageKey" atau properti lain saat mengkonfigurasi rute yang bisa Anda gunakan untuk mematikan. Selain itu, Anda dapat mengimplementasikan pendengar pada metode $ routeChangeSuccess dari objek $ route untuk mendengarkan keberhasilan penyelesaian perubahan rute.

Ketika pawang Anda menembak Anda mendapatkan kunci halaman, dan menggunakan kunci itu untuk menemukan elemen yang harus "AKTIF" untuk halaman ini, dan Anda menerapkan kelas AKTIF.

Perlu diingat Anda membutuhkan cara untuk membuat SEMUA elemen "DI AKTIF". Seperti yang Anda lihat, saya menggunakan kelas .pageKey pada item nav saya untuk mematikan semuanya, dan saya menggunakan .pageKey_ {PAGEKEY} untuk menyalakannya secara individual. Mengalihkan semuanya ke tidak aktif, akan dianggap sebagai pendekatan naif, berpotensi Anda akan mendapatkan kinerja yang lebih baik dengan menggunakan rute sebelumnya untuk membuat hanya item aktif yang tidak aktif, atau Anda dapat mengubah pemilih jquery untuk hanya memilih item aktif yang dibuat tidak aktif. Menggunakan jquery untuk memilih semua item yang aktif mungkin merupakan solusi terbaik karena ini memastikan semuanya dibersihkan untuk rute saat ini jika ada bug css yang mungkin ada pada rute sebelumnya.

Yang berarti mengubah baris kode ini:

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

untuk yang ini

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

Berikut ini beberapa contoh kode:

Diberikan navbar bootstrap dari

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

Dan modul sudut dan pengontrol seperti berikut:

<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>
Tandai At Ramp51
sumber
Anda perlu menggulir ke kanan untuk melihat nilai pageKey pada rute, itulah kunci untuk seluruh solusi ini.
Mark At Ramp51
16
Ini mungkin berhasil, tetapi bertentangan dengan saran umum untuk aplikasi Angular.js: di Angular Anda harus menahan diri dari bermain-main dengan DOM menggunakan jQuery; jika Anda harus menyentuh DOM, tulis arahan.
Paulo Scardine
ini sempurna, jika manipulasi dom mengganggu Anda, cukup tambahkan arahan pada .navbar, tambahkan $ broadcast event di routechangesuccess, $ rootScope. $ broadcast ('routeChanged', current.pageKey); dan kemudian tangkap di arahan Anda dan lakukan manipulasi dom di sana
Irshu
7

Anda benar-benar dapat menggunakan petunjuk 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>

atau:

Kontroler Header

/**
 * 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.'
      }
    ];
  });

Halaman indeks

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

Jika Anda menggunakan ui-utils, Anda mungkin juga tertarik dengan ui-router untuk mengelola tampilan parsial / bersarang.

Lèse majesté
sumber
Pendekatan ui-route sangat menggoda tetapi sejauh ini saya tidak berhasil membuatnya bekerja pada proyek yang dihasilkan oleh generator sudut Yeoman.
gabuzo
@ gabuzo: Apakah Anda menginstal angular-ui-utils via bower?
Lèse majesté
6

Saya menemukan semua jawaban ini agak terlalu rumit bagi saya, maaf. Jadi saya telah membuat arahan kecil yang harus bekerja berdasarkan per 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');
            });
        }
    };
});

Pemakaian:

<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>
Tom Fobear
sumber
Metode Anda hanya berfungsi setelah Anda mengklik tautan di bilah navigasi. Jika Anda memulai dengan URL yang "Foo", "Home" awalnya akan tetap dipilih. misal memulai di localhost: 9000 / # / kontak menyebabkan Home tampil terpilih di bilah navigasi.
Adam Plocher
5

Saya menggunakan arahan kelas-ng dengan $ location untuk mencapainya.

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

Ini membutuhkan navbar untuk berada di dalam Kontroler utama dengan akses ke layanan $ location seperti ini:

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

Anda dapat mencapai ini dengan bersyarat dalam ekspresi sudut, seperti:

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

Yang sedang berkata, saya menemukan arahan sudut menjadi cara yang lebih "tepat" untuk melakukannya, meskipun outsourcing banyak mini-logika ini agak dapat mencemari basis kode Anda.

Saya menggunakan persyaratan untuk penataan GUI sesekali selama pengembangan, karena ini sedikit lebih cepat daripada membuat arahan. Saya tidak bisa memberi tahu Anda sebuah contoh di mana mereka benar-benar tetap di basis kode lama. Pada akhirnya saya mengubahnya menjadi arahan atau menemukan cara yang lebih baik untuk menyelesaikan masalah.

JeffreyHammansson
sumber
4

Jika Anda menggunakan ui-router , contoh berikut harus memenuhi kebutuhan Anda berdasarkan komentar @ DanPantry pada jawaban yang diterima tanpa menambahkan kode sisi pengontrol:

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

Anda dapat memeriksa dokumen untuk info lebih lanjut.

Bryan CS
sumber
sempurna! pasti solusi terbersih
Aryeh Beitz
cukup sederhana solusi terbaik. siapa yang tidak menggunakan ui.router!
dewd
3

Jika Anda lebih suka tidak menggunakan AngularStrap maka arahan ini harus melakukan trik !. Ini adalah modifikasi dari 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>

Catatan: Kelas-kelas HTML di atas menganggap Anda menggunakan Bootstrap 3.x

John Schult
sumber
3

Inilah pendapat saya. Sedikit kombinasi jawaban ditemukan di pos ini. Saya memiliki kasus yang sedikit berbeda, jadi solusi saya melibatkan memisahkan menu ke dalam template sendiri untuk digunakan dalam Directive Definition Ojbect kemudian menambahkan navbar saya ke halaman yang saya butuhkan. Pada dasarnya, saya memiliki halaman login yang tidak ingin saya sertakan pada menu saya, jadi saya menggunakan ngInclude dan masukkan arahan ini ketika login:

PENGARAHAN:

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;

        }
    }
 }
});

TEMPLATE LANGSUNG (templat / 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 YANG TERMASUK ARAH

<comp-navbar/>

Semoga ini membantu

britztopher
sumber
1
Fungsi ini dapat disingkat menjadi hanya $ scope.isActive = function (viewLocation) {return viewLocation === $ location.path (); };
WP McNeill
2

Memperluas jawaban saya, saya membutuhkan ini untuk menangani struktur seperti ini.

-indeks

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

-tempat
--- tempat-daftar
--- tempat-edit
--- tempat-peta

jadi alih-alih mencocokkan, saya harus menggunakan indexOf, untuk memvalidasi tautan anak yang diformat agar sesuai dengan kondisi. Jadi untuk 'acara':

<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;
};}
M Sandoval
sumber
2

Ini adalah solusi sederhana

<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>
Marcelo Fernandez
sumber
1

Sehubungan dengan jawaban @ Olivier's AngularStrap, saya juga menerapkan jawaban kevinknelson dari: https://github.com/twbs/bootstrap/issues/9013 .

Secara native, navbar Bootstrap3 tidak dirancang untuk aplikasi satu halaman (misalnya Angular) dan dengan demikian menu ketika pada layar kecil tidak runtuh saat klik.

Tim S.
sumber
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>
Syed
sumber
Ini tidak berfungsi - ini tidak menambah kelas saat ini ke DOM
TheBlackBenzKid
1

Terima kasih kepada @Pylinux . Saya telah menggunakan tekniknya dan juga memodifikasinya untuk mendukung menu drop down "satu" (sub ul / li), karena itulah yang saya butuhkan. Lihat beraksi di tautan biola di bawah ini.

Diperbarui Fiddle berdasarkan jawaban pylinux - http://jsfiddle.net/abhatia/en4qxw6g/

Saya membuat tiga perubahan berikut, untuk mendukung menu drop-down satu tingkat:
1. Menambahkan nilai kelas dd (dropdown) untuk elemen "a" di bawah li yang perlu memiliki daftar sub ul.

         <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 Diperbarui untuk menambahkan logika baru berikut.

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


3. Diperbarui CSS untuk menambahkan yang berikut:

a.active {background-color:red;}

Semoga ini akan membantu seseorang yang ingin menerapkan menu dropdown tingkat tunggal.

abhishek
sumber
1

Gunakan objek sebagai variabel sakelar.
Anda dapat melakukan inline ini cukup sederhana dengan:

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

Setiap kali Anda mengklik tautan, objek sakelar digantikan oleh objek baru di mana hanya properti sakelar objek yang benar yang benar. Properti yang tidak terdefinisi akan dievaluasi sebagai false sehingga elemen yang bergantung padanya tidak akan memiliki kelas aktif yang ditugaskan.

Dario Mincioni
sumber
0

Anda juga dapat menggunakan arahan tautan aktif ini https://stackoverflow.com/a/23138152/1387163

Orang tua li akan mendapatkan kelas aktif ketika lokasi cocok / url :

<li>
    <a href="#!/url" active-link active-link-parent>
</li>
Eugene Fidelin
sumber
0

Saya sarankan menggunakan arahan pada tautan. Ini biola.

Tapi ini belum sempurna. Hati-hati dengan hashbangs;)

Berikut adalah javascript untuk direktif:

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

dan inilah bagaimana ini akan digunakan dalam 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>

setelah itu styling dengan css:

.active{ color:red; }
Kalpesh Prajapati
sumber
0

Hanya untuk menambahkan dua sen saya dalam debat saya telah membuat modul sudut murni (tanpa jquery), dan itu juga akan bekerja dengan hash url yang berisi data. ( ig #/this/is/path?this=is&some=data )

Anda cukup menambahkan modul sebagai dependensi dan auto-activeke salah satu leluhur menu. Seperti ini:

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

Dan modulnya terlihat seperti ini:

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

* (Tentu saja Anda bisa menggunakan bagian arahan)

** Perlu juga diperhatikan bahwa ini tidak bekerja untuk hash kosong ( ig example.com/# atau hanya example.com) yang dibutuhkan setidaknya example.com/#/atau adil example.com#/. Tapi ini terjadi secara otomatis dengan ngResource dan sejenisnya.

Pylinux
sumber
Itu tidak menyenangkan. Alasan menggunakan Angular adalah untuk kesederhanaan.
Tom Stickel
0

Ini melakukan trik untuk saya:

  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

maka Anda menggunakan jquery (berfungsi dengan sudut juga) untuk menambahkan kelas aktif

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

dan tentu saja css:

.active{background:red;}

ini berfungsi jika Anda memiliki html seperti ini:

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

ini akan menambah kelas aktif menggunakan url halaman dan warna latar belakang Anda menjadi merah jika Anda di www.somesite.com/ee thaen ee adalah 'aplikasi' dan itu akan aktif

elad perak
sumber
0

Ini sudah lama dijawab tetapi saya pikir saya akan berbagi dengan saya:

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

Templat:

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

Bagi yang menggunakan 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>

Untuk pencocokan tepat (mis. Negara bagian?) Gunakan $state.name === 'full/path/to/state'atauui-sref-active-eq="active"

Muli Yulzary
sumber
0

Inilah solusi lain untuk siapa saja yang mungkin tertarik. Keuntungan dari ini adalah ia memiliki lebih sedikit ketergantungan. Heck, itu bekerja tanpa server web juga. Jadi itu sepenuhnya sisi klien.

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>

Penjelasan:

Di sini kita membuat tautan secara dinamis dari model angular menggunakan direktif ng-repeat. Magic terjadi dengan metode selectTab()dan getTabClass()didefinisikan dalam controller untuk navbar ini yang disajikan di bawah ini.

Pengendali:

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

Penjelasan:

selectTab()Metode ini disebut menggunakan ng-clickdirektif. Jadi ketika tautan diklik, variabelnyaselectedTab diatur ke nama tautan ini. Dalam HTML Anda dapat melihat bahwa metode ini dipanggil tanpa argumen untuk tab Beranda sehingga akan disorot ketika halaman dimuat.

The getTabClass()metode ini disebut melalui ng-classdirektif dalam HTML. Metode ini memeriksa apakah tab itu sama dengan nilai selectedTabvariabel. Jika benar, ia mengembalikan "aktif" yang lain mengembalikan "" yang diterapkan sebagai nama kelas berdasarkan ng-classarahan. Lalu apa pun css yang telah Anda terapkan ke kelas activeakan diterapkan ke tab yang dipilih.

kovac
sumber
Apa yang terjadi ketika saya menavigasi ke tab lain dengan maksud lain?
Miguel Carvajal
Maksud kamu apa?
kovac
misalnya tautan di halaman yang membawa Anda ke halaman lain yang ada di dalam tab lain. Masuk akal?
Miguel Carvajal
Dalam hal ini saya pikir lebih baik menggunakan ui-router seperti yang disarankan oleh Muli Yulzary dalam jawaban di atas. ui-router memberikan status ke setiap url. Jadi, begitu seseorang mengklik tautan, pengguna akan diarahkan ke tautan itu dan keadaan aplikasi sudut akan diperbarui. Kemudian ui-sref = "active" akan menyorot tab. Berikut dokumentasi untuk angular 2: ui-router.github.io/ng2 . Selain itu, alih-alih menggunakan tampilan bootstrap normal di UI Bootstrap dilakukan untuk digunakan dengan aplikasi Angular. UI Bootstrap: angular-ui.github.io/bootstrap
kovac
0

Hanya Anda harus menambahkan active-class yang diperlukan dengan kode warna yang diperlukan.

Ex: ng-class="{'active': currentNavSelected}" ng-click="setNav"

Shankar Gangadhar
sumber