วิธีการตั้งค่าคลาสแอ็คทีฟ bootstrap navbar ด้วย Angular JS


306

หากฉันมี navbar ใน bootstrap กับรายการ

Home | About | Contact

ฉันจะตั้งค่าคลาสที่แอ็คทีฟสำหรับแต่ละไอเท็มเมนูได้อย่างไรเมื่อแอ็คทีฟ? นั่นคือฉันจะตั้งได้อย่างไรclass="active"เมื่อเส้นทางเชิงมุมอยู่ที่

  1. #/ สำหรับบ้าน
  2. #/about สำหรับหน้าเกี่ยวกับ
  3. #/contact สำหรับหน้าติดต่อ

เป็นไปได้ที่ซ้ำกันของMake Twitter Bootstrap navbar link active
givanse

10
สิ่งนี้คล้ายกัน แต่ไม่ใช่ "วิธีเชิงมุม" ในการเน้นปุ่มนำทาง
user1876508

เป็นไปได้ที่ซ้ำกันของตั้งค่าสไตล์แท็บที่ใช้งานกับ AngularJS
Amit G

หากคุณกำลังใช้เส้นทางเชิงมุมโปรดทราบว่าคำตอบที่สมบูรณ์ถูกฝังอยู่ทางลงด้านล่าง: stackoverflow.com/a/43822400/474189
Duncan Jones

คำตอบ:


598

วิธีที่สวยงามมากคือการใช้ ng-controller เพื่อเรียกใช้คอนโทรลเลอร์เดี่ยวนอก ng-view:

<div class="collapse navbar-collapse" ng-controller="HeaderController">
    <ul class="nav navbar-nav">
        <li ng-class="{ active: isActive('/')}"><a href="/">Home</a></li>
        <li ng-class="{ active: isActive('/dogs')}"><a href="/dogs">Dogs</a></li>
        <li ng-class="{ active: isActive('/cats')}"><a href="/cats">Cats</a></li>
    </ul>
</div>
<div ng-view></div>

และรวมอยู่ใน controllers.js:

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

10
ตั้งแต่ฉันยังใหม่กับเรื่องนี้ฉันจะขอบคุณถ้าคุณสามารถให้ตัวอย่างเกี่ยวกับวิธีที่จะทำให้มันเป็นคำสั่งส่วนหัวโปรด
mono68

41
ฉันขอแนะนำให้ใช้return $location.path().indexOf(viewLocation) == 0;แทนเพื่อให้คุณสามารถจับหน้ากับพารามิเตอร์ได้เช่นกัน
Sven Hecht

7
สิ่งนี้ทำให้งานเสร็จ แต่แทบจะไม่elegant- ชื่อเส้นทางเช่น/dogsจะต้องมีการทำซ้ำในการโทรไปที่isActive('/dogs')
wal

7
หากคุณใช้ UI เราเตอร์คุณสามารถใช้ui-sref-active/ui-sref-active-eqคำสั่งเช่น ui-sref-active-eq='active'หรือui-sref-active='active'เพื่อให้ได้ผลลัพธ์เดียวกัน
Dan Pantry

10
@SvenHecht ข้อกังวลของตรรกะนั้นคือลิงค์โฮมเพจ (/) จะจับคู่กับพา ธ อื่น
mwotton

51

ฉันเพียงแค่เขียนคำสั่งในการจัดการนี้เพื่อให้คุณสามารถเพิ่มแอตทริบิวต์bs-active-linkการปกครอง<ul>องค์ประกอบและเวลาใด ๆ เส้นทางที่มีการเปลี่ยนแปลงก็จะพบการเชื่อมโยงการจับคู่และเพิ่มชั้นเรียนที่สอดคล้องกันactive<li>

คุณสามารถดูได้ในการดำเนินการที่นี่: http://jsfiddle.net/8mcedv3b/

ตัวอย่าง HTML:

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

javascript:

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

1
ฉันชอบสิ่งนี้ดีกว่าคำตอบที่ยอมรับเพราะไม่มีการทำซ้ำข้อมูล config เช่นเส้นทางที่ตัวเองยังคงอยู่ในที่เดียวและมันก็ใช้งานได้ ..
Aaron Anodide

1
ทำงานให้ฉันโดยใช้ขอบเขต $ watch ("$ routeChangeSuccess", function () {.... แทนขอบเขต $ on ("$ routeChangeSuccess", function () {....
aemad

ต้องบิดนี้เล็กน้อยเพื่อจุดประสงค์ของฉันเอง แต่คำตอบที่น่ากลัว! เข้าใจง่ายพอ
Tony Anziano

38

คุณสามารถดูAngularStrap , คำสั่ง navbar ดูเหมือนจะเป็นสิ่งที่คุณกำลังมองหา:

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

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

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

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

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

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

วิธีใช้คำสั่งนี้:

  1. ดาวน์โหลด AngularStrap จากhttp://mgcrea.github.io/angular-strap/

  2. รวมสคริปต์ในหน้าของคุณหลังจาก bootstrap.js:
    <script src="lib/angular-strap.js"></script>

  3. เพิ่มคำสั่งในโมดูลของคุณ:
    angular.module('myApp', ['$strap.directives'])

  4. เพิ่มคำสั่งลงในแถบนำทางของคุณ:
    <div class="navbar" bs-navbar>

  5. เพิ่ม regexes ในแต่ละรายการ nav:
    <li data-match-route="/about"><a href="#/about">About</a></li>


1
ขอบคุณ สิ่งนี้ช่วยให้ฉันแก้ไขคำสั่งของฉันเอง (ความเข้าใจที่ขาดหายไปสำหรับฉันscope.$watch)
Ngure Nyaga

ทำไมelementตัวแปรถูกส่งไปยังตัวเลือก jquery $('...', element)
Lucio

@Lucio วิธีการใช้เวลา 2 ข้อโต้แย้ง - jQuery (ตัวเลือกบริบท) - อาร์กิวเมนต์ที่สองคือการผ่านบริบทของตัวเลือกทั้งองค์ประกอบ DOM แม่หรือวัตถุ jQuery อื่นเอง - อ่านเพิ่มเติมได้ที่นี่
CoderTR

มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน - ฉันต้องทำการเปลี่ยนแปลงอย่างใดอย่างหนึ่งอย่างไรก็ตามต่อmgcrea.github.io/angular-strapคำสั่งเพื่อเพิ่มไปยังโมดูลของคุณmgcrea.ngStrapไม่ได้$strap.directives
Vixxd

33

นี่เป็นวิธีง่ายๆที่ทำงานได้ดีกับ Angular

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

ภายในคอนโทรลเลอร์ AngularJS ของคุณ:

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

2
วิธีการที่ดี ฉันแก้ไขมันนิดหน่อย - ใช้คำสั่ง ng-class (ng-class = {active: isActive ('/ View1')}) และปรับปรุงฟังก์ชั่น isActive เพื่อคืนค่าจริง / เท็จแทนชื่อคลาสเอง
patelsan

ฉันได้คัดลอกทุกอย่างเช่นตัวอย่างของคุณและสำหรับฉัน $ location.path () ไม่ทำงาน ... เปลี่ยนเป็น $ location.url () และใช้งานได้!
เปาโลโอลีฟวีรา

14

หากคุณทำงานกับเราเตอร์ Angular เราท์เตอร์RouterActive directiveสามารถใช้งานได้อย่างหรูหรา:

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

2
ฉันคิดว่านี่ควรเป็นคำตอบที่ยอมรับได้ (อย่างน้อยเชิงมุม 2+) ทำไมจึงมีการใช้งานบางอย่างอยู่แล้ว แต่สำหรับ Bootstrap 3.3 activeคลาสควรอยู่ใน<li>(คุณสามารถวาง routerLinkActive กับ routerLink หรือ parent)
PhoneixS

3
หมายเหตุ: หากคุณใช้/เป็นหน้าแรกของคุณrouterLinkActiveจะพิจารณาว่าการใช้งานสำหรับ URL ใด ๆ เริ่มต้นด้วย/เช่น/foo/, /foo/barฯลฯ routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}"เพื่อให้ตรงกับว่าคุณจะต้อง
ดันแคนโจนส์

8

ก่อนอื่นปัญหานี้สามารถแก้ไขได้หลายวิธี วิธีนี้อาจไม่ได้หรูหราที่สุด แต่ก็ใช้งานได้อย่างแน่นอน

นี่เป็นวิธีง่ายๆที่คุณควรจะเพิ่มในโครงการใด ๆ คุณสามารถเพิ่ม "pageKey" หรือคุณสมบัติอื่น ๆ เมื่อคุณกำหนดค่าเส้นทางของคุณที่คุณสามารถใช้เพื่อปิดการใช้งาน นอกจากนี้คุณสามารถใช้ฟังในวิธี $ routeChangeSuccess ของวัตถุ $ route เพื่อรับฟังความสำเร็จของการเปลี่ยนเส้นทางที่สำเร็จ

เมื่อตัวจัดการของคุณเริ่มทำงานคุณจะได้รับรหัสของหน้าและใช้ปุ่มนั้นเพื่อค้นหาองค์ประกอบที่ต้องเป็น "ACTIVE" สำหรับหน้านี้และคุณจะใช้คลาส ACTIVE

โปรดทราบว่าคุณต้องการวิธีที่จะทำให้องค์ประกอบทั้งหมด "ใช้งานได้" อย่างที่คุณเห็นฉันกำลังใช้คลาส. pageKey บนรายการ nav ของฉันเพื่อปิดทั้งหมดและฉันใช้. pageKey_ {PAGEKEY} เพื่อเปิดแต่ละรายการ การเปลี่ยนพวกเขาทั้งหมดเป็นไม่ได้ใช้งานจะถือว่าเป็นวิธีการที่ไร้เดียงสาคุณอาจได้รับประสิทธิภาพที่ดีขึ้นโดยใช้เส้นทางก่อนหน้าเพื่อสร้างเฉพาะรายการที่ไม่ได้ใช้งานเท่านั้นหรือคุณสามารถเปลี่ยนตัวเลือก jquery เพื่อเลือกรายการที่ใช้งาน การใช้ jquery เพื่อเลือกไอเท็มที่ใช้งานอยู่ทั้งหมดน่าจะเป็นทางออกที่ดีที่สุดเพราะมันจะทำให้ทุกอย่างสะอาดขึ้นสำหรับเส้นทางปัจจุบันในกรณีที่มีข้อผิดพลาด css ใด ๆ ที่อาจมีอยู่ในเส้นทางก่อนหน้านี้

ซึ่งจะหมายถึงการเปลี่ยนรหัสบรรทัดนี้:

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

ถึงอันนี้

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

นี่คือตัวอย่างรหัสบางส่วน:

รับ bootstrap navbar ของ

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

และโมดูลเชิงมุมและตัวควบคุมดังต่อไปนี้:

<script type="text/javascript">

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

    }



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

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

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

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

        });

</script>

คุณต้องเลื่อนไปทางขวาเพื่อดูหน้าคีย์ค่าบนเส้นทางนั่นคือกุญแจสำคัญของโซลูชันทั้งหมดนี้
ทำเครื่องหมายที่ Ramp51

16
สิ่งนี้อาจใช้งานได้ แต่ขัดต่อคำแนะนำทั่วไปสำหรับแอป Angular.js: ใน Angular คุณควรหลีกเลี่ยงการยุ่งกับ DOM โดยใช้ jQuery หากคุณต้องแตะ DOM ให้เขียนคำสั่ง
เปาโล Scardine

นี่คือสิ่งที่สมบูรณ์แบบถ้าการจัดการ dom รบกวนคุณเพียงเพิ่มคำสั่งบน. navbar เพิ่มเหตุการณ์ $ broadcast ในเส้นทางการเปลี่ยนแปลงที่ประสบความสำเร็จ $ rootScope $ broadcast ('routeChanged', current.pageKey); แล้วจับมันตามคำสั่งของคุณและทำ
กิจวัตรที่

7

จริงๆคุณสามารถใช้มุม UI-utils ' ui-routeสั่ง:

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

หรือ:

ตัวควบคุมส่วนหัว

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

หน้าดัชนี

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

หากคุณใช้ ui-utils คุณอาจสนใจui-routerในการจัดการมุมมองบางส่วน / ซ้อนกัน


วิธีการของ ui-route เป็นสิ่งที่ดึงดูดใจมาก แต่จนถึงตอนนี้ฉันยังไม่สามารถจัดการกับมันได้ในโครงการที่สร้างโดยเครื่องกำเนิดไฟฟ้าเชิงมุมของ Yeoman
gabuzo

@gabuzo: คุณติดตั้ง angular-ui-utils ผ่าน bower หรือเปล่า?
Lèsemajesté

6

ฉันพบว่าคำตอบทั้งหมดเหล่านี้ค่อนข้างซับซ้อนสำหรับฉันขอโทษ ดังนั้นฉันได้สร้างคำสั่งเล็ก ๆ ที่ควรทำงานบนพื้นฐานต่อ navbar:

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

การใช้งาน:

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

วิธีการของคุณจะทำงานหลังจากที่คุณคลิกลิงก์ในแถบนำทางเท่านั้น หากคุณเริ่มต้นด้วย URL ที่เป็น "Foo" ระบบจะเลือก "หน้าแรก" เป็นครั้งแรก เช่นเริ่มจากlocalhost: 9000 / # / contactทำให้ Home ปรากฏในแถบนำทาง
Adam Plocher

5

ฉันใช้คำสั่ง ng-class พร้อม $ location เพื่อให้บรรลุ

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

มันต้องการให้ navbar อยู่ภายในตัวควบคุมหลักที่สามารถเข้าถึงบริการ $ location ได้ดังนี้:

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

4

คุณสามารถทำได้โดยมีเงื่อนไขในนิพจน์เชิงมุมเช่น:

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

ที่ถูกกล่าวว่าฉันจะหาคำสั่งเชิงมุมที่จะเป็นวิธีที่ "เหมาะสม" ในการทำมันแม้ว่าการเอาท์ซอร์สขนาดเล็กจำนวนมากออกจะทำให้ฐานรหัสของคุณสกปรก

ฉันใช้ conditionals สำหรับการใส่สไตล์ GUI ทุกครั้งในระหว่างการพัฒนาเพราะมันเร็วกว่าการสร้างคำสั่งเล็กน้อย ฉันไม่สามารถบอกคุณได้ถึงแม้ว่าพวกเขาจะยังคงอยู่ในฐานรหัสเป็นเวลานาน ในที่สุดฉันก็เปลี่ยนเป็นคำสั่งหรือหาวิธีที่ดีกว่าในการแก้ปัญหา


4

หากคุณใช้ui-routerตัวอย่างต่อไปนี้ควรตอบสนองความต้องการของคุณตามความคิดเห็นของ @ DanPantry เกี่ยวกับคำตอบที่ยอมรับโดยไม่ต้องเพิ่มโค้ดฝั่งควบคุม:

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

คุณสามารถตรวจสอบเอกสารเพื่อดูข้อมูลเพิ่มเติมได้


ที่สมบูรณ์แบบ! วิธีแก้ปัญหาที่แน่นอนที่สุด
Aryeh Beitz

เป็นทางออกที่ดีที่สุด ใครไม่ได้ใช้ui.router!
น้ำค้าง

3

หากคุณไม่ต้องการใช้AngularStrapคำสั่งนี้ควรใช้เคล็ดลับ! นี่คือการเปลี่ยนแปลงของhttps://stackoverflow.com/a/16231859/910764

JavaScript

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

HTML

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

หมายเหตุ:คลาส HTML ด้านบนถือว่าคุณใช้Bootstrap 3.x


3

นี่ฉันใช้มัน พบคำตอบเล็ก ๆ น้อย ๆ รวมอยู่ในโพสต์นี้ ฉันมีกรณีที่แตกต่างกันเล็กน้อยดังนั้นโซลูชันของฉันเกี่ยวข้องกับการแยกเมนูเป็นเทมเพลตของตัวเองเพื่อใช้ภายใน Directive Definition Ojbect จากนั้นเพิ่ม navbar ของฉันไปยังหน้าที่ฉันต้องการ โดยทั่วไปฉันมีหน้าเข้าสู่ระบบที่ฉันไม่ต้องการรวมเมนูของฉันดังนั้นฉันจึงใช้ ngInclude และแทรกคำสั่งนี้เมื่อเข้าสู่ระบบ:

DIRECTIVE:

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;

        }
    }
 }
});

DIRECTIVE TEMPLATE (เทมเพลต / 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 ซึ่งรวมถึง DIRECTIVE

<comp-navbar/>

หวังว่านี่จะช่วยได้


1
ฟังก์ชันสามารถย่อให้เหลือเพียง $ scope.isActive = function (viewLocation) {return viewLocation === $ location.path (); };
WP McNeill

2

การขยายคำตอบ myl ฉันต้องการสิ่งนี้เพื่อจัดการโครงสร้างเช่นนี้

-ดัชนี


- กิจกรรม<-active --- event-list
--- event-edit
--- event-map <-clicked

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

ดังนั้นแทนที่จะจับคู่ฉันต้องใช้ indexOf เพื่อตรวจสอบความถูกต้องของลิงก์เด็ก ๆ ที่ถูกจัดรูปแบบเพื่อให้ตรงกับเงื่อนไข ดังนั้นสำหรับ 'events':

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


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

2

นี่เป็นวิธีง่ายๆ

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

1

ร่วมกับคำตอบ AngularStrap ของ @ Olivier ฉันได้ใช้คำตอบของ kevinknelson จาก: https://github.com/twbs/bootstrap/issues/9013 https://github.com/twbs/bootstrap/issues/9013

โดยปกติแล้ว Bootstrap3 navbar ไม่ได้ออกแบบมาสำหรับแอพพลิเคชั่นหน้าเดียว (เช่น Angular) และทำให้เมนูเมื่อบนหน้าจอขนาดเล็กไม่ยุบเมื่อคลิก


1

JavaScript

/**
 * Main AngularJS Web Application
 */

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


/**
 * Setup Main Menu
 */

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

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

HTML

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

มันใช้งานไม่ได้ - มันไม่ได้เพิ่มคลาสปัจจุบันให้กับ DOM
TheBlackBenzKid

1

ขอขอบคุณที่@Pylinux ฉันใช้เทคนิคของเขาและปรับเปลี่ยนเพื่อรองรับเมนูดร็อปดาวน์ "หนึ่ง" (sub ul / li) ตามที่ฉันต้องการ ดูการทำงานในลิงค์ซอด้านล่าง

ซอ Fiddle ปรับปรุงตามคำตอบของ pylinux - http://jsfiddle.net/abhatia/en4qxw6g/

ฉันทำการเปลี่ยนแปลงสามอย่างต่อไปนี้เพื่อรองรับเมนูดร็อปดาวน์หนึ่งระดับ:
1. เพิ่มค่าคลาสของ dd (ดรอปดาวน์) สำหรับองค์ประกอบ "a" ภายใต้ li ซึ่งต้องมีรายการย่อย 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 เพื่อเพิ่มตรรกะใหม่ต่อไปนี้

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


3. อัปเดต CSS เพื่อเพิ่มสิ่งต่อไปนี้:

a.active {background-color:red;}

หวังว่านี่จะเป็นประโยชน์กับคนที่ต้องการใช้เมนูแบบเลื่อนลงระดับเดียว


1

ใช้วัตถุเป็นตัวแปรสวิตช์
คุณสามารถทำสิ่งนี้ได้ง่ายๆด้วย:

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

ทุกครั้งที่คุณคลิกที่ลิงค์วัตถุสวิทช์จะถูกแทนที่ด้วยวัตถุใหม่ซึ่งคุณสมบัติของวัตถุสวิตช์ที่ถูกต้องเท่านั้นที่เป็นจริง คุณสมบัติที่ไม่ได้กำหนดจะประเมินว่าเป็นเท็จดังนั้นองค์ประกอบที่ขึ้นอยู่กับพวกเขาจะไม่ได้รับการกำหนดคลาสที่ใช้งานอยู่



0

ฉันขอแนะนำให้ใช้คำสั่งในลิงค์ นี่คือซอ

แต่มันยังไม่สมบูรณ์แบบ ระวัง hashbangs;)

นี่คือ javascript สำหรับคำสั่ง:

angular.module('link', []).
  directive('activeLink', ['$location', function(location) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs, controller) {
        var clazz = attrs.activeLink;
        var path = attrs.href;
        path = path.substring(1); //hack because path does not return including hashbang
        scope.location = location;
        scope.$watch('location.path()', function(newPath) {
          if (path === newPath) {
            element.addClass(clazz);
          } else {
            element.removeClass(clazz);
          }
        });
      }
    };
  }]);

และนี่คือวิธีการใช้ใน html:

<div ng-app="link">
  <a href="#/one" active-link="active">One</a>
  <a href="#/two" active-link="active">One</a>
  <a href="#" active-link="active">home</a>
</div>

หลังจากนั้นจัดแต่งทรงผมด้วย CSS:

.active{ color:red; }

0

เพียงเพื่อเพิ่มสองเซ็นต์ของฉันในการอภิปรายฉันได้ทำโมดูลเชิงมุมบริสุทธิ์ (ไม่มี jQuery) และมันจะทำงานกับ URL แฮชที่มีข้อมูล ( ig #/this/is/path?this=is&some=data )

คุณเพียงแค่เพิ่มโมดูลเป็นการพึ่งพาและauto-activeหนึ่งในบรรพบุรุษของเมนู แบบนี้:

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

และโมดูลมีลักษณะดังนี้:

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

                setActive();

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

* (คุณสามารถใช้ส่วนของคำสั่งได้)

** มันก็คุ้มค่าที่จะสังเกตเห็นว่ามันใช้ไม่ได้กับแฮ็กเปล่า ( ig example.com/#หรือ just example.com) มันต้องมีอย่างน้อยexample.com/#/หรือแค่example.com#/นั้น แต่สิ่งนี้จะเกิดขึ้นโดยอัตโนมัติด้วย ngResource และสิ่งที่คล้ายกัน


นั่นเป็นเพียงที่น่ารังเกียจ เหตุผลที่ใช้ Angular คือเพื่อความเรียบง่าย
Tom Stickel

0

นี้ได้เคล็ดลับสำหรับฉัน:

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

จากนั้นคุณใช้ jquery (ทำงานร่วมกับเชิงมุมด้วย) เพื่อเพิ่มคลาสที่แอ็คทีฟ

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

และแน่นอน CSS:

.active{background:red;}

สิ่งนี้ใช้ได้ถ้าคุณมี html ของคุณเช่นนี้:

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

สิ่งนี้จะเพิ่มคลาสที่แอ็คทีฟโดยใช้ URL ของหน้าเว็บและทำให้สีพื้นหลังของคุณเป็นสีแดงหากคุณอยู่ใน www.somesite.com/ee thaen ee คือ 'แอป' และมันจะเปิดใช้งาน


0

นี่เป็นคำตอบที่ยาวนาน แต่ฉันคิดว่าฉันจะแบ่งปันวิธีของฉัน:

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

แม่แบบ:

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

สำหรับผู้ใช้ui-router:

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

สำหรับการจับคู่ที่ตรงกัน (เช่นรัฐที่ซ้อนกัน?) ให้ใช้$state.name === 'full/path/to/state'หรือui-sref-active-eq="active"


0

นี่เป็นอีกทางเลือกสำหรับทุกคนที่อาจสนใจ ข้อดีของมันคือมันมีการพึ่งพาน้อยลง Heck มันทำงานได้โดยไม่มีเว็บเซิร์ฟเวอร์ด้วย ดังนั้นมันจึงเป็นฝั่งไคลเอ็นต์อย่างสมบูรณ์

HTML:

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

คำอธิบาย:

ที่นี่เราจะสร้างการเชื่อมโยงแบบไดนามิกจากรูปแบบ angularjs ng-repeatโดยใช้คำสั่ง เวทย์มนตร์เกิดขึ้นกับวิธีการselectTab()และgetTabClass()กำหนดไว้ในตัวควบคุมสำหรับ navbar นี้ที่นำเสนอด้านล่าง

ควบคุม:

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

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

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

    var selectedTab = null;

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

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

คำอธิบาย:

selectTab()วิธีการที่เรียกว่าใช้ng-clickคำสั่ง ดังนั้นเมื่อมีการคลิกลิงค์ตัวแปรselectedTabจะถูกตั้งค่าเป็นชื่อของลิงค์นี้ ใน HTML คุณจะเห็นว่าวิธีการนี้เรียกว่าไม่มีข้อโต้แย้งใด ๆ สำหรับแท็บหน้าแรกเพื่อที่จะถูกเน้นเมื่อหน้าโหลด

getTabClass()วิธีการที่เรียกว่าผ่านng-classคำสั่งใน HTML เมธอดนี้ตรวจสอบว่าแท็บที่อยู่นั้นเหมือนกับค่าของselectedTabตัวแปรหรือไม่ ถ้าเป็นจริงมันจะส่งคืน "active" else จะส่งคืน "" ซึ่งใช้เป็นชื่อคลาสโดยng-classคำสั่ง จากนั้น css ใดก็ตามที่คุณใช้กับคลาสactiveจะถูกนำไปใช้กับแท็บที่เลือก


ฉันจะนำความสุขไปสู่แท็บอื่นด้วยค่าเฉลี่ยอื่น ๆ ได้อย่างไร?
Miguel Carvajal

คุณหมายถึงอะไร
kovac

ตัวอย่างเช่นลิงก์ในหน้าเว็บที่นำคุณไปสู่หน้าอื่นที่อยู่ในแท็บอื่น มีเหตุผล?
Miguel Carvajal

ในกรณีนี้ฉันคิดว่าควรใช้ ui-router ตามคำแนะนำของ Muli Yulzary ในการตอบคำถามข้างต้น ui-router กำหนดสถานะให้กับแต่ละ URL ดังนั้นเมื่อมีคนคลิกที่ลิงค์ผู้ใช้จะถูกส่งไปยังลิงก์นั้นและสถานะของแอพเชิงมุมจะได้รับการอัปเดต จากนั้น ui-sref = "active" จะเน้นแถบ นี่คือเอกสารเชิงมุม 2: ui-router.github.io/ng2 นอกจากนี้แทนที่จะใช้ bootstrap ปกติดู UI Bootstrap ทำเพื่อใช้กับแอป Angular UI Bootstrap: angular-ui.github.io/bootstrap
kovac

0

คุณจะต้องเพิ่มสิ่งที่จำเป็น activeคลาสที่ต้องการพร้อมรหัสสีที่ต้องการ

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.