Setel gaya tab aktif dengan AngularJS

144

Saya memiliki rute yang ditetapkan di AngularJS seperti ini:

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

Saya memiliki beberapa tautan di topbar yang ditata sebagai tab. Bagaimana saya bisa menambahkan kelas 'aktif' ke tab tergantung pada templat atau url saat ini?

Sergei Basharov
sumber
4
@AminMeyghani Bagaimana pertanyaan ini bisa menjadi duplikat dari pertanyaan, yang ditanyakan hampir setahun kemudian ?
Bupati

Jawaban:

274

Cara untuk mengatasi ini tanpa harus bergantung pada URL adalah dengan menambahkan atribut khusus ke setiap parsial selama $routeProviderkonfigurasi, seperti ini:

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

Paparkan $routedi controller Anda:

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

Atur activekelas berdasarkan pada tab aktif saat ini:

<li ng-class="{active: $route.current.activetab == 'dashboard'}"></li>
<li ng-class="{active: $route.current.activetab == 'lab'}"></li>
Rob Juurlink
sumber
3
ini adalah solusi terbaik yang pernah saya lihat sejauh ini karena mendukung url dinamis seperti / foo /: bar.
martinpaulucci
3
saya sebenarnya belum bisa membuatnya bekerja. apakah Anda bisa menyediakan plnkr?
PPPaul
9
Hanya satu hal: Lebih baik atur $scope.activeTab = $route.current.activetabagar Anda dapat menjaga html sedikit lebih bersih.
Christoph
2
Ini tidak berfungsi di AngularJS 1.0.8. $ route.current tidak terdefinisi.
Catfish
2
Gabungkan ini dengan $rootScopetrik @ Lucas di bawah untuk membuatnya tersedia di semua ruang lingkup.
colllin
134

Salah satu cara untuk melakukan ini adalah dengan menggunakan direktif ngClass dan layanan $ location. Dalam templat Anda, Anda bisa melakukan:

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

di mana isActiveakan ada fungsi dalam lingkup yang ditentukan seperti ini:

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

Inilah jsFiddle lengkap: http://jsfiddle.net/pkozlowski_opensource/KzAfG/

Mengulang ng-class="{active:isActive('/dashboard')}"pada setiap tab navigasi mungkin membosankan (jika Anda memiliki banyak tab) sehingga logika ini mungkin menjadi kandidat untuk arahan yang sangat sederhana.

pkozlowski.opensource
sumber
1
Butuh waktu lama sebelum saya menemukan 'arahan yang sangat sederhana' untuk menjadi sangat sederhana untuk ditulis, jadi saya telah memberikan satu di bawah ini. :-) Ini harus dapat digunakan kembali dalam berbagai konteks, tanpa konfigurasi non-deklaratif.
XML
1
Melihat jsFiddle, bagaimana Anda mengatur halaman aktif saat memuat halaman? Contoh ini hanya berfungsi ketika pengguna mengklik suatu opsi. Misalnya, Anda mungkin ingin 'beranda' disorot saat mendarat di beranda dari tautan eksternal.
thathurtabit
Ahh menggaruk kepalaku sedikit tentang ini. Terima kasih!
masterwok
41

Mengikuti saran Pavel untuk menggunakan arahan khusus, berikut adalah versi yang tidak perlu menambahkan payload ke routeConfig, super deklaratif, dan dapat diadaptasi untuk bereaksi pada level jalan apa pun, hanya dengan mengubah yang mana slice()Anda perhatikan. .

app.directive('detectActiveTab', 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" detect-active-tab="1">HOME</a>
                </li> 
            */

            // This var grabs the tab-level off the attribute, or defaults to 1
            var pathLevel = attrs.detectActiveTab || 1,
            // This var finds what the path is at the level specified
                pathToCheck = $location.path().split('/')[pathLevel] || 
                  "current $location.path doesn't reach this level",
            // This var finds grabs the same level of the href attribute
                tabLink = attrs.href.split('/')[pathLevel] || 
                  "href doesn't include this level";
            // Above, we use the logical 'or' operator to provide a default value
            // in cases where 'undefined' would otherwise be returned.
            // This prevents cases where undefined===undefined, 
            // possibly causing multiple tabs to be 'active'.

            // now compare the two:
            if (pathToCheck === tabLink) {
              element.addClass("active");
            }
            else {
              element.removeClass("active");
            }
        });
      }
    };
  });

Kami mencapai tujuan kami dengan mendengarkan $routeChangeSuccessacara, bukan dengan menempatkannya $watchdi jalur. Saya bekerja di bawah keyakinan bahwa ini berarti logika harus berjalan lebih jarang, karena saya pikir jam tangan menyala pada setiap $digestsiklus.

Aktifkan itu dengan meneruskan argumen level jalan Anda pada deklarasi direktif. Ini menentukan potongan apa dari $ location.path () saat ini yang ingin Anda cocokkan dengan hrefatribut Anda .

<li class="nav_tab"><a href="#/home" detect-active-tab="1">HOME</a></li>

Jadi, jika tab Anda bereaksi terhadap level dasar jalur, buat argumen '1'. Jadi, ketika location.path () adalah "/ home", itu akan cocok dengan "# / home" di href. Jika Anda memiliki tab yang seharusnya bereaksi ke tingkat kedua, atau ketiga, atau ke 11 jalur, sesuaikan. Pemotongan dari 1 atau lebih ini akan mem-bypass '#' jahat di href, yang akan hidup pada indeks 0.

Satu-satunya persyaratan adalah bahwa Anda memanggil pada <a>, karena elemen tersebut mengasumsikan keberadaan hrefatribut, yang akan dibandingkan dengan jalur saat ini. Namun, Anda dapat beradaptasi dengan cukup mudah untuk membaca / menulis elemen induk atau anak, jika Anda lebih suka memohon pada <li>sesuatu atau sesuatu. Saya menggali ini karena Anda dapat menggunakannya kembali dalam banyak konteks hanya dengan memvariasikan argumen pathLevel. Jika kedalaman untuk membaca diasumsikan dalam logika, Anda perlu beberapa versi dari direktif untuk digunakan dengan beberapa bagian navigasi.


EDIT 3/18/14: Solusinya tidak cukup digeneralisasi, dan akan aktif jika Anda mendefinisikan argumen untuk nilai 'activeTab' yang mengembalikan undefinedkeduanya $location.path(), dan elemen href. Karena: undefined === undefined. Diperbarui untuk memperbaiki kondisi itu.

Saat mengerjakannya, saya menyadari seharusnya ada versi yang bisa Anda deklarasikan pada elemen induk, dengan struktur template seperti ini:

<nav id="header_tabs" find-active-tab="1">
    <a href="#/home" class="nav_tab">HOME</a>
    <a href="#/finance" class="nav_tab">Finance</a>
    <a href="#/hr" class="nav_tab">Human Resources</a>
    <a href="#/quarterly" class="nav_tab">Quarterly</a>
</nav>

Perhatikan bahwa versi ini tidak lagi menyerupai HTML gaya Bootstrap. Tapi, ini lebih modern dan menggunakan lebih sedikit elemen, jadi saya tidak setuju. Versi direktif ini, plus yang asli, sekarang tersedia di Github sebagai modul drop-in yang bisa Anda nyatakan sebagai dependensi. Saya akan senang untuk Bower-ize mereka, jika ada yang benar-benar menggunakannya.

Juga, jika Anda menginginkan versi yang kompatibel dengan bootstrap yang menyertakannya <li>, Anda dapat menggunakan modul angular-ui-bootstrap Tab , yang saya pikir keluar setelah posting asli ini, dan yang mungkin bahkan lebih deklaratif daripada yang ini. Ini kurang ringkas untuk hal-hal dasar, tetapi memberi Anda beberapa opsi tambahan, seperti tab yang dinonaktifkan dan acara deklaratif yang diaktifkan dan dinonaktifkan.

XML
sumber
4
Saya tidak percaya tidak ada yang benar-benar memberikan suara ini! Ini 2 sen saya. Meskipun ada kesalahan kecil dalam kode, saya pikir 'tabLevel' seharusnya 'activeTab'. Dan untuk gaya Bootstrap, Anda mungkin ingin menambahkan kelas 'aktif' ke elemen LI alih-alih elemen A. Tetapi ini hanya membutuhkan perubahan kecil.
David Lin
1
Anda benar tentang activeTab, @ Davidvidin. Diedit. Tapi, saya tidak jatuh cinta pada struktur Bootstrap, karenanya ada perbedaan yang disengaja di sana. Bahkan, saya mulai berpikir bahwa abstraksi nav mungkin bukan milik ulsama sekali, dan mungkin hanya koleksi jangkar, dibungkus oleh navelemen pengelompokan atau lainnya. Berurusan dengan lapisan perantara liditambahkan kompleksitas tanpa imbalan, terutama sekarang kita memiliki navelemen yang kita miliki untuk memperjelas apa yang terjadi.
XML
Ini sederhana dan cemerlang. Saya terkejut tidak ada yang seperti ini di Angular untuk memeriksa rute yang Anda lalui.
Intellix
1
Untuk membuatnya bekerja dengan bootstrap3, yang harus Anda lakukan adalah mengubah `element.addClass (" active ");` menjadi `element.parent ('li'). AddClass (" active ");` Saya pikir ini bisa lebih baik bernama demikian, sesuatu seperti is-active-tab insead dari active-tab yang tampaknya menyatakan bahwa tab itu aktif. Kalau tidak, ini adalah arahan yang sangat bagus. Melihat perubahan ini dalam jawaban dengan @domi
boatcoder
Solusi terbaik di halaman ini, tidak percaya ia memiliki sedikit upvotes.
Karolis
27

@ rob-juurlink Saya sedikit memperbaiki solusi Anda:

alih-alih setiap rute membutuhkan tab aktif; dan perlu mengatur tab aktif di setiap controller saya melakukan ini:

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

Dan HTMLnya terlihat seperti ini. Activetab hanyalah url yang terkait dengan rute itu. Ini hanya menghilangkan kebutuhan untuk menambahkan kode di setiap controller (menyeret dependensi seperti $ route dan $ rootScope jika ini adalah satu-satunya alasan mereka digunakan)

<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>
Lucas
sumber
Terima kasih banyak atas modifikasi ini. Sangat bagus. Apakah Anda punya saran untuk mengatur tab aktif saat halaman pertama kali dimuat?
Hairgami_Master
2
tergantung apa yang kamu inginkan. biasanya Anda akan memiliki '/' url menjadi pengontrol utama Anda. dengan begitu ketika pengguna membuka url Anda, itu akan memuat pengontrol itu dan mengatur tab itu sebagai aktif. Pada contoh di atas saya tidak memiliki url '/', jadi jika itu kasus Anda cukup tambahkan .otherwise () $ routeProvider. when ('/ dashboard', {templateUrl: 'partials / dashboard.html', controller: Ctrl1}). when ('/ lab', {templateUrl: 'partials / lab.html', controller: Ctrl2}). sebaliknya ({redirectTo: '/ dashboard'}); semoga berhasil!
Lucas
Banyak terima kasih @Lucas. Itu membantu. Beberapa alasan saya harus menambahkan simbol # ke rute utama saya ketika ('# /', {controller: FormsController, templateUrl: 'partials / dashboard.html'}).
Hairgami_Master
Saya lebih suka cara ini. Memiliki rootScope dan melakukan apa saja di mana saja
wrivas
16

Mungkin arahan seperti ini dapat menyelesaikan masalah Anda: 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);
                }
            });
        }

    };

}]);
kfis
sumber
1
Perhatikan bahwa Anda harus menggunakan $ mengamati jika href berisi ekspresi: docs.angularjs.org/guide/directive#Attributes . Lihat biola diperbarui: jsfiddle.net/p3ZMR/10
Narretz
14

Solusi paling sederhana di sini:

Bagaimana cara mengatur kelas aktif bootstrap navbar dengan Angular JS?

Yang mana:

Gunakan 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();
    };
}
Zymotik
sumber
2
setuju, sejauh ini yang paling mudah
AngeloS
12

Saya sarankan menggunakan modul state.ui yang tidak hanya mendukung pandangan banyak dan bersarang tetapi juga membuat jenis pekerjaan ini sangat mudah (kode di bawah ini dikutip):

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

Layak dibaca.

David Lin
sumber
4

Berikut adalah versi lain dari XMLillies dengan perubahan LI domi yang menggunakan string pencarian alih-alih tingkat jalur. Saya pikir ini sedikit lebih jelas apa yang terjadi pada use case saya.

statsApp.directive('activeTab', function ($location) {
  return {
    link: function postLink(scope, element, attrs) {
      scope.$on("$routeChangeSuccess", function (event, current, previous) {
        if (attrs.href!=undefined) { // this directive is called twice for some reason
          // The activeTab attribute should contain a path search string to match on.
          // I.e. <li><a href="#/nested/section1/partial" activeTab="/section1">First Partial</a></li>
          if ($location.path().indexOf(attrs.activeTab) >= 0) {
            element.parent().addClass("active");//parent to get the <li>
          } else {
            element.parent().removeClass("active");
          }
        }
      });
    }
  };
});

HTML sekarang terlihat seperti:

<ul class="nav nav-tabs">
  <li><a href="#/news" active-tab="/news">News</a></li>
  <li><a href="#/some/nested/photos/rawr" active-tab="/photos">Photos</a></li>
  <li><a href="#/contact" active-tab="/contact">Contact</a></li>
</ul>
Dave Rapin
sumber
3

Saya menemukan anwser XMLilley yang terbaik dan paling mudah beradaptasi dan tidak mengganggu.

Namun saya memiliki kesalahan kecil.

Untuk digunakan dengan bootstrap nav, berikut adalah cara saya memodifikasinya:

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

Saya menambahkan "if (attrs.href! = Undefined)" karena fungsi ini dipanggil dua kali, yang kedua kalinya menghasilkan kesalahan.

Adapun 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>
domi
sumber
nvm, itu salahku ini dipanggil dua kali. Saya kira "jika (attrs.href! = Tidak terdefinisi)" tidak diperlukan.
domi
3

Contoh bootstrap.

Jika Anda menggunakan Angulars built in routing (ngview) arahan ini dapat digunakan:

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

        }
    };
}]);

Dengan asumsi markup Anda terlihat seperti ini:

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

Saya suka ini karena saya dapat mengatur nama kelas yang Anda inginkan di atribut Anda.

Michael Falck Wedelgård
sumber
2

Anda juga dapat dengan mudah menyuntikkan lokasi ke dalam ruang lingkup dan menggunakannya untuk mengurangi gaya navigasi:

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

Kemudian gunakan di ng-class:

<li ng-class="{active: location.path() == '/search'}">
  <a href="/search">Search><a/>
</li>
Der Hochstapler
sumber
bukankah seharusnya $ root.location.path () di markup?
Irshu
@Irshu: Itu mungkin bisa lebih bersih, tetapi pendekatan di atas berhasil juga untuk saya.
Der Hochstapler
2

cara alternatif adalah menggunakan ui-sref-active

Arahan yang bekerja bersama ui-sref untuk menambahkan kelas ke elemen ketika status direktif ui-sref terkait aktif, dan menghapusnya saat tidak aktif. Kasus penggunaan utama adalah menyederhanakan tampilan khusus menu navigasi yang mengandalkan ui-sref, dengan membuat tombol menu status "aktif" tampak berbeda, membedakannya dari item menu yang tidak aktif.

Pemakaian:

ui-sref-active = 'class1 class2 class3' - class "class1", "class2", dan "class3" masing-masing ditambahkan ke elemen direktif ketika keadaan ui-sref terkait aktif, dan dihapus ketika tidak aktif.

Contoh:
Diberikan templat berikut,

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

ketika status aplikasi adalah "app.user", dan berisi parameter status "pengguna" dengan nilai "bilbobaggins", HTML yang dihasilkan akan muncul sebagai

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

Nama kelas diinterpolasi satu kali selama arahan tautan waktu (setiap perubahan lebih lanjut ke nilai interpolasi diabaikan). Beberapa kelas dapat ditentukan dalam format yang dipisahkan ruang.

Gunakan direktif ui-sref-opts untuk meneruskan opsi ke $ state.go (). Contoh:

<a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
George Botros
sumber
Terima kasih. Ini sangat berguna saat bekerja dalam kerangka ion!
Avijit Gupta
1

Saya setuju dengan posting Rob tentang memiliki atribut khusus di controller. Rupanya saya tidak punya cukup perwakilan untuk berkomentar. Inilah jsfiddle yang diminta:

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

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

jasontwong
sumber
Saya suka pendekatan berbasis data ke daftar tautan. Dan, beberapa mungkin memilih untuk memindahkan array tautan ke layanan / pabrik.
Grant Lindsay
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();
    };
  });

Dan gunakan yang di bawah ini dalam templat:

<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>
Yeshodhan Kulkarni
sumber
0

Saya membutuhkan solusi yang tidak memerlukan perubahan pada controller, karena untuk beberapa halaman kami hanya membuat template dan tidak ada controller sama sekali. Berkat komentator sebelumnya yang menyarankan menggunakan $routeChangeSuccesssaya datang dengan sesuatu seperti ini:

# Directive
angular.module('myapp.directives')
.directive 'ActiveTab', ($route) ->
  restrict: 'A'

  link: (scope, element, attrs) ->
    klass = "active"

    if $route.current.activeTab? and attrs.flActiveLink is $route.current.activeTab
      element.addClass(klass)

    scope.$on '$routeChangeSuccess', (event, current) ->
      if current.activeTab? and attrs.flActiveLink is current.activeTab
        element.addClass(klass)
      else
        element.removeClass(klass)

# Routing
$routeProvider
.when "/page",
  templateUrl: "page.html"
  activeTab: "page"
.when "/other_page",
  templateUrl: "other_page.html"
  controller: "OtherPageCtrl"
  activeTab: "other_page"

# View (.jade)
a(ng-href='/page', active-tab='page') Page
a(ng-href='/other_page', active-tab='other_page') Other page

Itu tidak tergantung pada URL dan karenanya sangat mudah untuk mengaturnya untuk setiap sub halaman dll.

szimek
sumber
0

Saya tidak ingat di mana saya menemukan metode ini, tetapi cukup sederhana dan berfungsi dengan baik.

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;
  } 
cfranklin
sumber
0

Jika Anda menggunakan ngRoute (untuk perutean) maka aplikasi Anda akan memiliki konfigurasi di bawah,

angular
  .module('appApp', [
    'ngRoute'
 ])
config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl',
        controllerAs: 'main'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl',
        controllerAs: 'about'
      })
}
});

Sekarang, tambahkan saja controller dalam konfigurasi ini seperti di bawah ini,

angular
      .module('appApp', [
        'ngRoute'
     ])
    config(function ($routeProvider) {
        $routeProvider
          .when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl',
            activetab: 'main'
          })
          .when('/about', {
            templateUrl: 'views/about.html',
            controller: 'AboutCtrl',
            activetab: 'about'
          })
    }
    })
  .controller('navController', function ($scope, $route) {
    $scope.$route = $route;
  });

Seperti yang telah Anda sebutkan tab aktif di konfigurasi Anda, sekarang Anda hanya perlu menambahkan kelas aktif di tag <li>atau Anda <a>. Suka,

ng-class="{active: $route.current.activetab == 'about'}"

Yang berarti, setiap kali pengguna mengklik pada halaman, ini akan secara otomatis mengidentifikasi tab saat ini dan menerapkan kelas css aktif.

Saya harap ini membantu!

imbond
sumber
-3

Datang ke sini untuk solusi .. meskipun solusi di atas berfungsi dengan baik tetapi menemukan mereka sedikit rumit tidak perlu. Bagi orang yang masih mencari solusi yang mudah dan rapi, itu akan melakukan tugas dengan sempurna.

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