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?


306

Nếu tôi có một thanh điều hướng trong bootstrap với các mục

Home | About | Contact

Làm cách nào để đặt lớp hoạt động cho từng mục menu khi chúng hoạt động? Đó là, làm thế nào tôi có thể thiết lập class="active"khi tuyến đường góc là

  1. #/ cho gia đình
  2. #/about cho trang về
  3. #/contact cho trang liên hệ


10
Điều này tương tự, nhưng không phải là một "cách góc cạnh" để làm nổi bật các nút điều hướng.
dùng1876508


Nếu bạn đang sử dụng định tuyến Angular , xin lưu ý rằng câu trả lời hoàn hảo được chôn xuống bên dưới: stackoverflow.com/a/43822400/474189 .
Duncan Jones

Câu trả lời:


598

Một cách rất hay là sử dụng bộ điều khiển ng để chạy một 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();
    };
}

10
Vì tôi chưa quen với điều này nên tôi sẽ đánh giá cao nếu bạn có thể cung cấp một ví dụ về cách đưa điều này vào một chỉ thị tiêu đề, làm ơn.
mono68

41
Tôi sẽ đề nghị sử dụng return $location.path().indexOf(viewLocation) == 0;thay thế để bạn cũng có thể bắt các trang có tham số
Sven Hecht

7
Đây được công việc làm nhưng hầu như nó elegant- tên đường ví dụ như /dogsphải được lặp lại ở các cuộc gọi đếnisActive('/dogs')
wal

7
Nếu bạn đang sử dụng Bộ định tuyến UI, thì bạn có thể sử dụng các lệnh ui-sref-active/ui-sref-active-eq. ui-sref-active-eq='active'hoặc ui-sref-active='active'để đạt được kết quả tương tự
Dan Pantry

10
@SvenHecht Mối quan tâm với logic đó là liên kết trang chủ (/) sẽ khớp với mọi đường dẫn khác.
mw Bông

51

Tôi vừa viết một lệnh để xử lý việc này, vì vậy bạn chỉ cần thêm thuộc tính bs-active-linkvào <ul>phần tử cha và bất cứ khi nào tuyến đường thay đổi, nó sẽ tìm liên kết phù hợp và thêm activelớp vào tương ứng <li>.

Bạn có thể thấy nó hoạt động ở đây: http://jsfiddle.net/8mcedv3b/

Ví dụ 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
Tôi thích điều này tốt hơn câu trả lời được chấp nhận vì không có sự trùng lặp dữ liệu cấu hình, tức là các tuyến đường vẫn chỉ ở một nơi và điều này chỉ hoạt động ..
Aaron Anodide 7/11/2015

1
đã làm việc cho tôi bằng cách sử dụng scope. $ watch ("$ routeChangeSuccess", function () {.... thay vì scope. $ on ("$ routeChangeSuccess", function () {....
aemad

Phải điều chỉnh điều này một chút cho mục đích của riêng tôi, nhưng câu trả lời tuyệt vời! Đủ dễ hiểu
Tony Anziano

38

Bạn có thể xem AngularStrap , chỉ thị thanh điều hướng dường như là thứ bạn đang tìm kiếm:

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

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

Để sử dụng chỉ thị này:

  1. Tải xuống AngularStrap từ http://mgcrea.github.io/angular-strap/

  2. Bao gồm tập lệnh trên trang của bạn sau bootstrap.js:
    <script src="lib/angular-strap.js"></script>

  3. Thêm các chỉ thị vào mô-đun của bạn:
    angular.module('myApp', ['$strap.directives'])

  4. Thêm chỉ thị vào thanh điều hướng của bạn:
    <div class="navbar" bs-navbar>

  5. Thêm biểu thức chính trên mỗi mục điều hướng:
    <li data-match-route="/about"><a href="#/about">About</a></li>


1
Cảm ơn. Điều này giúp tôi sửa chữa chỉ thị của riêng mình (cái nhìn sâu sắc còn thiếu đối với tôi là scope.$watch)
Ngure Nyaga

Tại sao elementbiến được chuyển đến bộ chọn jquery? $('...', element)
Lucio

@Lucio phương thức lấy 2 đối số - jQuery (bộ chọn, ngữ cảnh) - đối số thứ hai là để chuyển ngữ cảnh của bộ chọn, hoặc là phần tử DOM cha hoặc chính đối tượng jQuery khác - đọc thêm tại đây
CoderTR

Điều này hoạt động hoàn hảo đối với tôi - tuy nhiên, tôi đã phải thực hiện một thay đổi, mỗi mgcrea.github.io/angular-strap chỉ thị để thêm vào mô-đun của bạn mgcrea.ngStrapkhông phải là$strap.directives
Vixxd

33

Đây là một cách tiếp cận đơn giản, hoạt động tốt với 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>

Trong bộ điều khiển AngularJS của bạn:

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

2
Cách tiếp cận tốt đẹp. Tôi đã sửa đổi nó một chút - chỉ thị ng-class đã sử dụng (ng-class = {active: isActive ('/ View1')}) và cập nhật hàm isActive để trả về true / false thay vì tên lớp.
patelsan

Tôi đã sao chép mọi thứ như ví dụ của bạn và đối với tôi $ location.path () không hoạt động ... đã chuyển sang $ location.url () và nó đã hoạt động!
Paulo Oliveira

14

Nếu bạn đang làm việc với bộ định tuyến Angular, chỉ thị RouterLinkActive có thể được sử dụng thực sự thanh lịch:

<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
Tôi nghĩ rằng đây nên là câu trả lời được chấp nhận (ít nhất là cho 2+ góc cạnh), tại sao thực hiện một cái gì đó đã được thực hiện? Nhưng đối với Bootstrap 3.3, activelớp phải nằm trong <li>(bạn có thể đặt bộ định tuyếnLinkActive với bộ định tuyếnLink hoặc cha mẹ của nó)
PhoneixS

3
Lưu ý: nếu bạn sử dụng /làm trang chủ của bạn, routerLinkActivesẽ xem xét rằng hoạt động cho bất kỳ URL bắt đầu với /, ví dụ như /foo/, /foo/barvv Để phù hợp chính xác, bạn cần routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}".
Duncan Jones

8

Đầu tiên và quan trọng nhất, vấn đề này có thể được giải quyết bằng nhiều cách. Cách này có thể không phải là thanh lịch nhất, nhưng nó chắc chắn hoạt động.

Đây là một giải pháp đơn giản mà bạn có thể thêm vào bất kỳ dự án nào. Bạn chỉ có thể thêm "pageKey" hoặc một số thuộc tính khác khi bạn định cấu hình tuyến đường mà bạn có thể sử dụng để khóa. Ngoài ra, bạn có thể triển khai trình nghe trên phương thức $ routeChangeSuccess của đối tượng $ route để lắng nghe việc hoàn thành thay đổi tuyến.

Khi trình xử lý của bạn kích hoạt, bạn nhận được khóa trang và sử dụng phím đó để xác định các phần tử cần là "HOẠT ĐỘNG" cho trang này và bạn áp dụng lớp HOẠT ĐỘNG.

Hãy nhớ rằng bạn cần một cách để làm cho TẤT CẢ các yếu tố "TRONG HOẠT ĐỘNG". Như bạn có thể thấy tôi đang sử dụng lớp .pageKey trên các mục điều hướng của mình để tắt tất cả chúng và tôi đang sử dụng .pageKey_ {PAGEKEY} để bật chúng riêng lẻ. Chuyển tất cả sang không hoạt động, sẽ được coi là một cách tiếp cận ngây thơ, có khả năng bạn sẽ có hiệu suất tốt hơn bằng cách sử dụng tuyến trước đó để chỉ các mục hoạt động không hoạt động hoặc bạn có thể thay đổi bộ chọn jquery để chỉ chọn các mục hoạt động để không hoạt động. Sử dụng jquery để chọn tất cả các mục hoạt động có lẽ là giải pháp tốt nhất vì nó đảm bảo mọi thứ được dọn sạch cho tuyến đường hiện tại trong trường hợp có bất kỳ lỗi css nào có thể có trên tuyến trước đó.

Điều đó có nghĩa là thay đổi dòng mã này:

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

cái này

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

Đây là một số mã mẫu:

Đưa ra một thanh điều hướng bootstrap của

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

Và một mô-đun góc và bộ điều khiển như sau:

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

Bạn cần cuộn sang phải để xem các giá trị pageKey trên các tuyến đường, đó là chìa khóa cho toàn bộ giải pháp này.
Đánh dấu tại Ramp51

16
Điều này có thể hoạt động, nhưng trái với lời khuyên chung cho các ứng dụng Angular.js: trong Angular, bạn không nên làm phiền với DOM bằng jQuery; nếu bạn phải chạm vào DOM, hãy viết một lệnh.
Paulo Scardine

điều này là hoàn hảo, nếu thao tác dom làm phiền bạn, chỉ cần thêm một lệnh trên .navbar, thêm một sự kiện phát sóng $ trong Routechangesuccess, $ rootScope. $ Broadcast ('routeChanged', current.pageKey); và sau đó nắm bắt nó theo chỉ thị của bạn và thực hiện các thao tác dom ở đó
Irshu

7

Bạn thực sự có thể sử dụng góc-ui-utils ' ui-routechỉ thị:

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

hoặc là:

Bộ điều khiển tiêu đề

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

Trang mục lục

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

Nếu bạn đang sử dụng ui-utils, bạn cũng có thể quan tâm đến ui-router để quản lý các chế độ xem một phần / lồng nhau.


Cách tiếp cận tuyến đường rất quyến rũ nhưng cho đến nay tôi đã không quản lý để làm cho nó hoạt động trong dự án được tạo ra bởi máy phát góc của Yeoman.
gabuzo

@gabuzo: Bạn đã cài đặt angular-ui-utils thông qua bower?
Lèse majesté

6

Tôi thấy tất cả những câu trả lời này hơi phức tạp đối với tôi, xin lỗi. Vì vậy, tôi đã tạo ra một lệnh nhỏ nên hoạt động trên cơ sở mỗi thanh điều hướng:

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

Sử dụng:

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

Phương pháp của bạn chỉ hoạt động sau khi bạn nhấp vào một liên kết trong thanh điều hướng. Nếu bạn bắt đầu với một URL là "Foo", "Trang chủ" ban đầu sẽ được chọn. ví dụ: bắt đầu trên localhost: 9000 / # / contact khiến Home xuất hiện được chọn trong thanh điều hướng.
Adam Plocher

5

Tôi sử dụng chỉ thị ng-class với $ location để đạt được nó.

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

Nó yêu cầu thanh điều hướng phải ở trong Bộ điều khiển chính có quyền truy cập vào dịch vụ định vị $ như thế này:

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

4

Bạn có thể đạt được điều này với một điều kiện trong một biểu thức góc, chẳng hạn như:

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

Điều đó đang được nói, tôi thấy một chỉ thị góc cạnh là cách làm "đúng đắn" hơn, mặc dù việc thuê ngoài rất nhiều logic nhỏ này có thể gây ô nhiễm cơ sở mã của bạn.

Tôi sử dụng các điều kiện để tạo kiểu GUI mỗi lần trong quá trình phát triển, vì nó nhanh hơn một chút so với việc tạo các lệnh. Tôi không thể nói với bạn một ví dụ mặc dù chúng thực sự tồn tại trong cơ sở mã lâu dài. Cuối cùng, tôi hoặc biến nó thành một chỉ thị hoặc tìm một cách tốt hơn để giải quyết vấn đề.


4

Nếu bạn sử dụng bộ định tuyến ui , ví dụ sau sẽ đáp ứng nhu cầu của bạn dựa trên nhận xét của @ DanPantry về câu trả lời được chấp nhận mà không cần thêm bất kỳ mã phía bộ điều khiển nào:

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

Bạn có thể kiểm tra các tài liệu để biết thêm thông tin về nó.


hoàn hảo! chắc chắn là giải pháp sạch nhất
Aryeh Beitz

khá đơn giản là giải pháp tốt nhất đi. ai không dùng ui.router!
sương

3

Nếu bạn không muốn sử dụng AngularStrap thì lệnh này sẽ thực hiện thủ thuật!. Đây là bản sửa đổi của 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>

Lưu ý: Các lớp HTML ở trên giả sử bạn đang sử dụng Bootstrap 3.x


3

Đây là của tôi trên đó. Một chút kết hợp các câu trả lời được tìm thấy trên bài đăng này. Tôi đã có một trường hợp hơi khác, vì vậy giải pháp của tôi liên quan đến việc tách menu thành mẫu riêng của nó để được sử dụng trong Ojbect Định nghĩa Chỉ thị, sau đó thêm thanh điều hướng của tôi vào trang tôi cần. Về cơ bản, tôi đã có một trang đăng nhập mà tôi không muốn đưa vào menu của mình, vì vậy tôi đã sử dụng ngInclude và chèn chỉ thị này khi đăng nhập:

TRỰC TIẾP:

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;

        }
    }
 }
});

MẪU TRỰC TIẾP (mẫu / 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 MÀ BAO GỒM TRỰC TIẾP

<comp-navbar/>

Hi vọng điêu nay co ich


1
Hàm có thể được rút ngắn thành chỉ $ scope.isActive = function (viewLocation) {return viewLocation === $ location.path (); };
WP McNeill

2

Mở rộng câu trả lời của tôi, tôi cần điều này để xử lý một cấu trúc như thế này.

-mục lục

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

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

Vì vậy, thay vì khớp, tôi phải sử dụng indexOf, để xác thực các liên kết con được định dạng để phù hợp với điều kiện. Vì vậy, đối với 'sự kiện':

<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

Đây là một giải pháp đơn giản

<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

Cùng với câu trả lời AngularStrap của @ Olivier, tôi cũng đã triển khai câu trả lời của kevinknelson từ: https://github.com/twbs/bootstrap/issues/9013 .

Về cơ bản, thanh điều hướng Bootstrap3 không được thiết kế cho một ứng dụng một trang (ví dụ Angular) và do đó menu khi trên màn hình nhỏ không bị sập khi nhấp.


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>

Điều này không hoạt động - nó không thêm lớp hiện tại vào DOM
TheBlackBenzKid

1

Cảm ơn @Pylinux . Tôi đã sử dụng kỹ thuật của anh ấy và cũng sửa đổi nó để hỗ trợ trình đơn thả xuống "một" (sub ul / li), vì đó là những gì tôi cần. Xem nó trong hành động trong liên kết fiddle dưới đây.

Fiddle được cập nhật dựa trên câu trả lời của pylinux - http://jsfiddle.net/abhatia/en4qxw6g/

Tôi đã thực hiện ba thay đổi sau đây, để hỗ trợ trình đơn thả xuống một cấp:
1. Đã thêm giá trị lớp của dd (thả xuống) cho phần tử "a" dưới li cần có danh sách phụ 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. Cập nhật Javascript để thêm logic mới sau đây.

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


3. Cập nhật CSS để thêm vào như sau:

a.active {background-color:red;}

Hy vọng rằng điều này sẽ hữu ích cho ai đó muốn thực hiện trình đơn thả xuống cấp đơn.


1

Sử dụng một đối tượng như một biến chuyển đổi.
Bạn có thể thực hiện nội tuyến này khá đơn giản với:

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

Mỗi lần bạn nhấp vào một liên kết, đối tượng chuyển đổi được thay thế bằng một đối tượng mới trong đó chỉ có thuộc tính đối tượng chuyển đổi đúng là đúng. Các thuộc tính không xác định sẽ đánh giá là sai và vì vậy các phần tử phụ thuộc vào chúng sẽ không được gán lớp hoạt động.



0

Tôi đề nghị sử dụng một chỉ thị trên một liên kết. Đây là câu đố.

Nhưng nó chưa hoàn hảo. Coi chừng các hashbang;)

Đây là javascript cho chỉ thị:

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

và đây là cách nó sẽ được sử dụng trong 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>

sau đó tạo kiểu với css:

.active{ color:red; }

0

Chỉ cần thêm hai xu của tôi vào cuộc tranh luận, tôi đã tạo ra một mô-đun góc thuần túy (không có jquery), và nó cũng sẽ hoạt động với các hàm băm chứa dữ liệu. ( ig #/this/is/path?this=is&some=data )

Bạn chỉ cần thêm mô-đun như một phụ thuộc và auto-activevào một trong những tổ tiên của menu. Như thế này:

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

Và mô-đun trông như thế này:

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

* (Tất nhiên bạn chỉ có thể sử dụng phần chỉ thị)

** Cũng đáng lưu ý rằng điều này không hoạt động đối với băm trống ( ig example.com/# hoặc chỉ example.com) nó cần phải có ít nhất example.com/#/hoặc chỉ example.com#/. Nhưng điều này xảy ra tự động với ngResource và tương tự.


Điều đó thật khó chịu. Lý do để sử dụng Angular là vì đơn giản.
Tom Stickel

0

Điều này đã lừa tôi:

  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

sau đó bạn sử dụng jquery (cũng hoạt động với góc cạnh) để thêm lớp hoạt động

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

và tất nhiên là css:

.active{background:red;}

Điều này hoạt động nếu bạn có html của bạn như thế này:

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

điều này sẽ vô tình thêm lớp hoạt động bằng cách sử dụng url trang và tô màu nền của bạn thành màu đỏ nếu trong www.somesite.com/ee thaen ee của bạn là 'ứng dụng' và nó sẽ hoạt động


0

Điều này đã được trả lời từ lâu nhưng tôi nghĩ tôi muốn chia sẻ theo cách của mình:

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

Bản mẫu:

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

Đối với những người sử dụng 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>

Để khớp chính xác (ví dụ: trạng thái lồng nhau?) Sử dụng $state.name === 'full/path/to/state'hoặcui-sref-active-eq="active"


0

Đây là một giải pháp khác cho bất cứ ai có thể quan tâm. Ưu điểm của việc này là nó có ít phụ thuộc hơn. Heck, nó hoạt động mà không có một máy chủ web quá. Vì vậy, nó hoàn toàn là phía khách hàng.

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>

Giải trình:

Ở đây chúng tôi đang tạo các liên kết động từ một mô hình angularjs bằng cách sử dụng lệnh ng-repeat. Phép thuật xảy ra với các phương thức selectTab()getTabClass()được định nghĩa trong bộ điều khiển cho thanh điều hướng này được trình bày bên dưới.

Điều khiển:

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

Giải trình:

selectTab()phương pháp được gọi là sử dụng ng-clickchỉ thị. Vì vậy, khi liên kết được nhấp, biến selectedTabđược đặt thành tên của liên kết này. Trong HTML, bạn có thể thấy rằng phương thức này được gọi mà không có bất kỳ đối số nào cho tab Trang chủ để nó sẽ được tô sáng khi tải trang.

Các getTabClass()phương pháp được gọi là thông qua ng-classchỉ thị trong HTML. Phương thức này kiểm tra xem tab nằm trong nó có giống với giá trị của selectedTabbiến không. Nếu đúng, nó trả về "hoạt động" khác trả về "" được áp dụng làm tên lớp theo ng-classchỉ thị. Sau đó, bất cứ css nào bạn đã áp dụng cho lớp activesẽ được áp dụng cho tab đã chọn.


Điều gì xảy ra là tôi điều hướng đến một tab khác bằng bất kỳ ý nghĩa nào khác?
Miguel Carvajal

Ý anh là gì?
kovac

ví dụ: một liên kết trong trang đưa bạn đến một trang khác nằm trong tab khác. Có ý nghĩa?
Miguel Carvajal

Trong trường hợp đó tôi nghĩ tốt hơn là sử dụng bộ định tuyến ui theo đề xuất của Muli Yulzary trong câu trả lời ở trên. ui-router gán trạng thái cho mỗi url. Vì vậy, một khi ai đó nhấp vào liên kết, người dùng sẽ được chuyển đến liên kết đó và trạng thái của ứng dụng góc cạnh sẽ được cập nhật. Sau đó ui-sref = "active" sẽ làm nổi bật tab. Đây là tài liệu cho góc 2: ui-router.github.io/ng2 . Ngoài ra, thay vì sử dụng bootstrap thông thường, hãy xem UI Bootstrap được sử dụng với các ứng dụng Angular. UI Bootstrap: angular-ui.github.io/bootstrap
kovac

0

Chỉ cần bạn sẽ phải thêm activelớp bắt buộc với mã màu yêu cầu.

Ví dụ: ng-class="{'active': currentNavSelected}" ng-click="setNav"

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.