Đặt kiểu tab hoạt động với AngularJS


144

Tôi có các tuyến được đặt trong AngularJS như thế này:

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

Tôi có một số liên kết trên topbar được tạo kiểu như các tab. Làm cách nào tôi có thể thêm lớp 'hoạt động' vào một tab tùy thuộc vào mẫu hoặc url hiện tại?



4
@AminMeyghani Làm thế nào câu hỏi này có thể trùng lặp với câu hỏi, được hỏi gần như năm sau ?
Nhiếp chính

Câu trả lời:


274

Một cách để giải quyết vấn đề này mà không cần phải dựa vào URL là thêm thuộc tính tùy chỉnh cho mọi bộ phận trong khi $routeProviderđịnh cấu hình, như sau:

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

Tiếp xúc $routetrong bộ điều khiển của bạn:

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

Đặt activelớp dựa trên tab hoạt động hiện tại:

<li ng-class="{active: $route.current.activetab == 'dashboard'}"></li>
<li ng-class="{active: $route.current.activetab == 'lab'}"></li>

3
đây là giải pháp tốt nhất tôi từng thấy cho đến nay vì nó hỗ trợ các url động như / foo /: bar.
martinpaulucci

3
tôi thực sự đã không thể làm việc này bạn có thể cung cấp một plnkr?
PPPaul

9
Chỉ có một điều: Thiết lập tốt hơn $scope.activeTab = $route.current.activetabđể bạn có thể giữ html sạch hơn một chút.
Christoph

2
Điều này không hoạt động trong AngularJS 1.0.8. $ route.c hiện không xác định.
Cá trê

2
Kết hợp điều này với $rootScopethủ thuật của @ Lucas dưới đây để làm cho nó có sẵn trong tất cả các phạm vi.
colllin

134

Một cách để làm điều này là bằng cách sử dụng lệnh ngClass và dịch vụ định vị $. Trong mẫu của bạn, bạn có thể làm:

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

nơi isActivesẽ là một hàm trong một phạm vi được xác định như thế này:

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

Dưới đây là jsFiddle hoàn chỉnh: http://jsfiddle.net/pkozlowski_opensource/KzAfG/

Lặp lại ng-class="{active:isActive('/dashboard')}"trên mỗi tab điều hướng có thể rất tẻ nhạt (nếu bạn có nhiều tab) vì vậy logic này có thể là một ứng cử viên cho một lệnh rất đơn giản.


1
Phải mất một thời gian dài trước khi tôi tìm thấy "những chỉ thị rất đơn giản" để thực sự rất đơn giản để viết, vì vậy tôi đã cung cấp một hướng dẫn dưới đây. :-) Nó có thể được tái sử dụng trong nhiều ngữ cảnh khác nhau, không có cấu hình không khai báo.
XML

1
Nhìn vào jsFiddle, làm thế nào để bạn thiết lập trang hiện tại hoạt động khi tải trang? Ví dụ chỉ hoạt động khi người dùng nhấp vào một tùy chọn. Ví dụ: bạn có thể muốn điều hướng 'nhà' được tô sáng khi hạ cánh trên trang chủ từ một liên kết bên ngoài.
đó là

Ahh đã gãi đầu tôi một chút về điều này. Cảm ơn!
masterwok

41

Theo lời khuyên của Pavel để sử dụng chỉ thị tùy chỉnh, đây là phiên bản không yêu cầu thêm tải trọng vào tuyếnConfig, siêu khai báo và có thể được điều chỉnh để phản ứng với bất kỳ cấp nào của đường dẫn, chỉ cần thay đổi mức độ nào slice()bạn đang chú ý .

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

Chúng tôi đang hoàn thành mục tiêu của mình bằng cách lắng nghe $routeChangeSuccesssự kiện, thay vì đặt một $watchcon đường. Tôi lao động theo niềm tin rằng điều này có nghĩa là logic nên chạy ít thường xuyên hơn, vì tôi nghĩ rằng đồng hồ bắn vào mỗi $digestchu kỳ.

Gọi nó bằng cách chuyển đối số cấp đường dẫn của bạn trên khai báo lệnh. Điều này xác định đoạn nào của $ location.path () hiện tại mà bạn muốn khớp với hrefthuộc tính của mình .

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

Vì vậy, nếu các tab của bạn sẽ phản ứng với mức cơ sở của đường dẫn, hãy tạo đối số '1'. Do đó, khi location.path () là "/ home", nó sẽ khớp với "# / home" trong href. Nếu bạn có các tab sẽ phản ứng với cấp độ thứ hai hoặc thứ ba hoặc thứ 11 của đường dẫn, hãy điều chỉnh cho phù hợp. Việc cắt lát này từ 1 trở lên sẽ bỏ qua '#' bất chính trong href, sẽ sống ở chỉ số 0.

Yêu cầu duy nhất là bạn gọi vào một <a>, vì phần tử đang giả sử sự hiện diện của một hrefthuộc tính, nó sẽ so sánh với đường dẫn hiện tại. Tuy nhiên, bạn có thể thích ứng khá dễ dàng để đọc / ghi phần tử cha hoặc con, nếu bạn muốn gọi trên <li>hoặc một cái gì đó. Tôi khai thác điều này bởi vì bạn có thể sử dụng lại nó trong nhiều ngữ cảnh bằng cách thay đổi đối số pathLevel. Nếu độ sâu để đọc từ được giả định trong logic, bạn cần nhiều phiên bản của lệnh để sử dụng với nhiều phần của điều hướng.


EDIT 3/18/14: Giải pháp được khái quát hóa không đầy đủ và sẽ kích hoạt nếu bạn xác định một đối số cho giá trị của 'activeTab' trả về undefinedcả hai $location.path()và phần tử href. Bởi vì : undefined === undefined. Cập nhật để khắc phục tình trạng đó.

Khi làm việc trên đó, tôi nhận ra rằng đã có một phiên bản mà bạn có thể khai báo trên phần tử cha, với cấu trúc mẫu như thế này:

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

Lưu ý rằng phiên bản này không còn giống với HTML kiểu Bootstrap nữa. Nhưng, nó hiện đại hơn và sử dụng ít yếu tố hơn, vì vậy tôi là một phần của nó. Phiên bản chỉ thị này, cộng với bản gốc, hiện có sẵn trên Github dưới dạng mô-đun thả xuống, bạn chỉ có thể khai báo là phụ thuộc. Tôi rất vui khi Bower-ize cho họ, nếu có ai thực sự sử dụng chúng.

Ngoài ra, nếu bạn muốn có một phiên bản tương thích bootstrap bao gồm <li>, bạn có thể sử dụng mô-đun Tab angular-ui-bootstrap , mà tôi nghĩ đã xuất hiện sau bài đăng gốc này, và có lẽ còn mang tính khai báo hơn cả bài này. Nó ít súc tích hơn cho các công cụ cơ bản, nhưng cung cấp cho bạn một số tùy chọn bổ sung, như các tab bị vô hiệu hóa và các sự kiện khai báo kích hoạt kích hoạt và hủy kích hoạt.


4
Tôi không thể tin rằng không ai thực sự bỏ phiếu này! Đây là 2 xu của tôi. Mặc dù có một lỗi nhỏ trong mã, tôi nghĩ rằng 'tabLevel' được coi là 'activeTab'. Và đối với kiểu Bootstrap, bạn có thể muốn thêm lớp 'active' vào phần tử LI thay vì phần tử A. Nhưng điều này chỉ đòi hỏi thay đổi nhỏ.
David Lin

1
Bạn hoàn toàn chính xác về activeTab, @DavidLin. Đã chỉnh sửa. Nhưng, tôi không thích cấu trúc của Bootstrap, do đó có một sự khác biệt có chủ ý ở đó. Trên thực tế, tôi bắt đầu nghĩ rằng sự trừu tượng điều hướng có thể không thuộc về ultất cả, và có lẽ chỉ nên là bộ sưu tập các neo, được bao bọc bởi một navhoặc một yếu tố nhóm khác. Đối phó với lớp trung gian liđược thêm vào sự phức tạp mà không phải trả tiền, đặc biệt là bây giờ chúng ta có navyếu tố theo ý của mình để làm rõ những gì đang diễn ra.
XML

Điều này là đơn giản và rực rỡ. Tôi đã ngạc nhiên khi không có thứ gì như thế này ở Angular để kiểm tra tuyến đường mà bạn đi.
Intellix

1
Để làm cho nó hoạt động với bootstrap3, tất cả những gì bạn phải làm là thay đổi `Element.addClass (" active ");` thành `Element.parent ('li'). AddClass (" active ");` Tôi nghĩ rằng nó có thể tốt hơn tên mặc dù, một cái gì đó như là chủ động-tab INSEAD của hoạt động-tab mà dường như để tuyên bố tab đang hoạt động. Nếu không, đây là một chỉ thị nghiêm túc tốt đẹp. Xem thay đổi này trong câu trả lời của @domi
Boatcoder

Giải pháp tốt nhất trên trang này, không thể tin rằng nó có quá ít sự ủng hộ.
Karolis

27

@ rob-juurlink Tôi đã cải thiện một chút về giải pháp của bạn:

thay vì mỗi tuyến cần một tab hoạt động; và cần thiết lập tab hoạt động trong mỗi bộ điều khiển Tôi làm điều này:

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

Và HTML trông như thế này. Activetab chỉ là url liên quan đến tuyến đường đó. Điều này chỉ loại bỏ nhu cầu thêm mã trong mỗi bộ điều khiển (kéo theo các phụ thuộc như $ route và $ rootScope nếu đây là lý do duy nhất chúng được sử dụng)

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

Rất cám ơn cho sự sửa đổi này. Rất đẹp. Bạn có bất kỳ đề xuất nào để đặt tab hoạt động khi trang tải lần đầu không?
Hairgami_Master

2
Phụ thuộc vào những gì bạn muốn. thông thường bạn có url '/' là bộ điều khiển chính của bạn. theo cách đó khi người dùng truy cập url của bạn, nó sẽ tải bộ điều khiển đó và đặt tab đó là hoạt động. Trong ví dụ ở trên, tôi không có url '/', vì vậy nếu đó là trường hợp của bạn chỉ cần thêm một .therwise () $ routeProvider. khi ('/ bảng điều khiển', {templateUrl: 'partials / dashboard.html', bộ điều khiển: Ctrl1}). khi ('/ lab', {templateUrl: 'partials / lab.html', bộ điều khiển: Ctrl2}). nếu không ({redirectTo: '/ dashboard'}); may mắn nhất!
Lucas

Rất cám ơn @Lucas. Điều đó đã giúp. Một số lý do khiến tôi phải thêm biểu tượng # vào tuyến đường chính của mình - khi ('# /', {bộ điều khiển: FormsContoder, templateUrl: 'partials / dashboard.html'}).
Hairgami_Master

Tôi thích cách này. Có rootScope và làm bất cứ điều gì ở bất cứ đâu
wrivas

16

Có thể một lệnh như thế này có thể giải quyết vấn đề của bạn: 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>

Mã não

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

    };

}]);

1
Lưu ý rằng bạn phải sử dụng $ obs nếu href chứa một biểu thức: docs.angularjs.org/guide/directive#Attribut . Xem fiddle cập nhật: jsfiddle.net/p3ZMR/10
Narretz

14

Giải pháp đơn giản nhất tại đây:

Làm cách nào để thiết lập lớp hoạt động của thanh điều khiển bootstrap với Angular JS?

Đó là:

Sử dụng bộ điều khiển ng để chạy bộ điều khiển duy nhất bên ngoài chế độ xem 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>

và bao gồm trong controls.js:

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

2
đồng ý, cho đến nay là dễ nhất
AngeloS

12

Tôi khuyên bạn nên sử dụng mô-đun state.ui không chỉ hỗ trợ nhiều chế độ xem và lồng nhau mà còn làm cho loại công việc này trở nên rất dễ dàng (mã dưới đây được trích dẫn):

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

Đáng đọc.


4

Đây là một phiên bản khác của XMLillies với thay đổi LI sử dụng chuỗi tìm kiếm thay vì cấp độ đường dẫn. Tôi nghĩ rằng đây là một chút rõ ràng hơn những gì xảy ra cho trường hợp sử dụng của tôi.

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 bây giờ trông như:

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

3

Tôi đã tìm thấy anwser của XMLille là tốt nhất và dễ thích nghi nhất và không xâm phạm.

Tuy nhiên tôi đã có một trục trặc nhỏ.

Để sử dụng với bootstrap nav, đây là cách tôi sửa đổi nó:

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

Tôi đã thêm "if (attrs.href! = Không xác định)" bởi vì chức năng này được gọi là hai lần, lần thứ hai tạo ra lỗi.

Đối với 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>

nvm, đó là lỗi của tôi, nó được gọi là hai lần. Tôi đoán "if (attrs.href! = Không xác định)" là không cần thiết.
domi

3

Ví dụ về Bootstrap.

Nếu bạn đang sử dụng Angenses được xây dựng trong định tuyến (ngview), lệnh này có thể được sử dụng:

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

        }
    };
}]);

Giả sử đánh dấu của bạn trông như thế này:

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

Tôi thích điều này là vì nó có thể đặt tên lớp bạn muốn trong thuộc tính của bạn.


2

Bạn cũng có thể chỉ cần đưa vị trí vào phạm vi và sử dụng vị trí đó để khấu trừ kiểu cho điều hướng:

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

Sau đó sử dụng nó trong ng-class:

<li ng-class="{active: location.path() == '/search'}">
  <a href="/search">Search><a/>
</li>

không nên là $ root.location.path () trong đánh dấu?
Irshu

@Irshu: Điều đó có thể có thể sạch hơn, nhưng cách tiếp cận trên cũng có hiệu quả với tôi.
Der Hochstapler

2

một cách khác là sử dụng ui-sref-active

Một lệnh hoạt động cùng với ui-sref để thêm các lớp vào một phần tử khi trạng thái của lệnh ui-sref có liên quan đang hoạt động và loại bỏ chúng khi nó không hoạt động. Trường hợp sử dụng chính là để đơn giản hóa sự xuất hiện đặc biệt của các menu điều hướng dựa trên ui-sref, bằng cách nút nút trạng thái "hoạt động" xuất hiện khác nhau, phân biệt với các mục menu không hoạt động.

Sử dụng:

ui-sref-active = 'class1 class2 class3' - các lớp "class1", "class2" và "class3" được thêm vào phần tử chỉ thị khi trạng thái của ui-sref có liên quan hoạt động và bị xóa khi không hoạt động.

Ví dụ:
Cho mẫu sau,

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

khi trạng thái ứng dụng là "app.user" và chứa tham số trạng thái "người dùng" có giá trị "bilbobaggins", HTML kết quả sẽ xuất hiện dưới dạng

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

Tên lớp được nội suy một lần trong thời gian liên kết chỉ thị (mọi thay đổi tiếp theo đối với giá trị nội suy đều bị bỏ qua). Nhiều lớp có thể được chỉ định trong một định dạng phân tách không gian.

Sử dụng chỉ thị ui-sref-opts để chuyển các tùy chọn sang $ state.go (). Thí dụ:

<a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>

Cảm ơn. Nó thực sự hữu ích khi làm việc trong khung ion!
Avijit Gupta

1

Tôi đồng ý với bài viết của Rob về việc có một thuộc tính tùy chỉnh trong bộ điều khiển. Rõ ràng tôi không có đủ đại diện để bình luận. Đây là jsfiddle đã được yêu cầu:

mẫu 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 mẫu

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/


Tôi thích cách tiếp cận dựa trên dữ liệu vào danh sách các liên kết. Và, một số có thể chọn di chuyển mảng liên kết vào một dịch vụ / nhà máy.
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();
    };
  });

Và sử dụng dưới đây trong mẫu:

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

0

Tôi cần một giải pháp không yêu cầu thay đổi đối với bộ điều khiển, vì đối với một số trang, chúng tôi chỉ hiển thị các mẫu và không có bộ điều khiển nào cả. Cảm ơn những người bình luận trước đây đã đề xuất sử dụng $routeChangeSuccesstôi đã đưa ra một cái gì đó như thế này:

# 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

Nó không phụ thuộc vào URL và do đó, thật dễ dàng để thiết lập nó cho bất kỳ trang phụ nào, v.v.


0

Tôi không thể nhớ nơi tôi tìm thấy phương pháp này, nhưng nó khá đơn giản và hoạt động tốt.

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

0

Nếu bạn đang sử dụng ngRoute (để định tuyến) thì ứng dụng của bạn sẽ có cấu hình bên dưới,

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

Bây giờ, chỉ cần thêm một bộ điều khiển trong cấu hình này giống như bên dưới,

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

Như bạn đã đề cập tab hoạt động trong cấu hình của mình, bây giờ bạn chỉ cần thêm lớp hoạt động trong thẻ <li>hoặc <a>thẻ của mình. Giống,

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

Có nghĩa là, bất cứ khi nào người dùng nhấp vào trang về, điều này sẽ tự động xác định tab hiện tại và áp dụng lớp css hoạt động.

Tôi hi vọng cái này giúp được!


-3

Đến đây để tìm giải pháp .. mặc dù các giải pháp trên đang hoạt động tốt nhưng thấy chúng hơi phức tạp không cần thiết. Đối với những người vẫn đang tìm kiếm một giải pháp dễ dàng và gọn gàng, nó sẽ thực hiện nhiệm vụ một cách hoàn hảo.

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.