ตั้งค่าสไตล์แท็บที่ใช้งานด้วย AngularJS


144

ฉันมีเส้นทางที่กำหนดไว้ใน AngularJS เช่นนี้:

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

ฉันมีลิงค์บางอันบนแถบด้านบนที่มีสไตล์เป็นแท็บ ฉันจะเพิ่มคลาส 'active' ลงในแท็บโดยขึ้นอยู่กับเทมเพลตหรือ url ปัจจุบันได้อย่างไร


เป็นไปได้ที่ซ้ำกันของฉันจะใช้ bootstrap navbar class แอ็คทีฟกับ Angular JS
AJ Meyghani

4
@AminMeyghani คำถามนี้จะซ้ำกันได้อย่างไรของคำถามที่ถูกถามเกือบปีต่อมา ?
ผู้สำเร็จราชการแผ่นดิน

คำตอบ:


274

วิธีแก้ปัญหานี้โดยไม่ต้องพึ่งพา URL คือการเพิ่มแอตทริบิวต์ที่กำหนดเองให้กับทุกส่วนระหว่าง$routeProviderการกำหนดค่าเช่นนี้:

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

เปิดเผย$routeในตัวควบคุมของคุณ:

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

ตั้งค่าactiveคลาสตามแท็บที่ใช้งานอยู่ในปัจจุบัน:

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

3
นี่เป็นทางออกที่ดีที่สุดที่ฉันเคยเห็นเพราะมันรองรับ URL แบบไดนามิกเช่น / foo /: bar
martinpaulucci

3
ที่จริงฉันไม่สามารถทำงานนี้ได้ คุณจะสามารถให้ plnkr ได้หรือไม่?
PPPaul

9
มีเพียงสิ่งเดียว: การตั้งค่าที่ดีกว่า$scope.activeTab = $route.current.activetabเพื่อให้คุณสามารถทำให้ html สะอาดขึ้นเล็กน้อย
Christoph

2
สิ่งนี้ไม่ทำงานใน AngularJS 1.0.8 $ route.current ไม่ได้ถูกกำหนด
ปลาดุก

2
รวมสิ่งนี้เข้ากับ$rootScopeเคล็ดลับของ @ Lucas ด้านล่างเพื่อให้พร้อมใช้งานในทุกขอบเขต
colllin

134

วิธีหนึ่งในการทำสิ่งนี้คือการใช้คำสั่ง ngClass และบริการ $ location ในแม่แบบของคุณคุณสามารถทำได้:

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

โดยที่isActiveฟังก์ชันในขอบเขตที่กำหนดดังนี้:

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

นี่คือ jsFiddle ที่สมบูรณ์: http://jsfiddle.net/pkozlowski_opensource/KzAfG/

การทำซ้ำng-class="{active:isActive('/dashboard')}"ในแต่ละแท็บการนำทางอาจน่าเบื่อ (ถ้าคุณมีหลายแท็บ) ดังนั้นตรรกะนี้อาจเป็นตัวเลือกสำหรับคำสั่งที่ง่ายมาก


1
ฉันใช้เวลานานก่อนที่ฉันจะพบ 'คำสั่งที่ง่ายมาก' จริง ๆ แล้วเขียนได้ง่ายมาก :-) ควรนำมาใช้ซ้ำได้ในหลากหลายบริบทโดยไม่มีการกำหนดค่าที่ไม่ประกาศ
XML

1
ดูที่ jsFiddle คุณจะตั้งค่าหน้าปัจจุบันที่ใช้งานในการโหลดหน้าได้อย่างไร ตัวอย่างทำงานเฉพาะเมื่อผู้ใช้คลิกตัวเลือก ตัวอย่างเช่นคุณอาจต้องการไฮไลต์การนำทางที่ "บ้าน" เมื่อเชื่อมโยงไปถึงหน้าแรกจากลิงก์ภายนอก
thathurtabit

อ่าเกาหัวของฉันในเรื่องนี้นิดหน่อย ขอบคุณ!
masterwok

41

ตามคำแนะนำของพาเวลที่จะใช้คำสั่งที่กำหนดเองนี่เป็นรุ่นที่ต้องเพิ่มไม่มีน้ำหนักบรรทุกไป routeConfig เป็นที่เปิดเผยสุดและสามารถนำไปปรับใช้กับการตอบสนองต่อระดับของเส้นทางใด ๆ โดยเพียงแค่การเปลี่ยนที่slice()ว่าคุณกำลังให้ความสนใจกับ .

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

เราบรรลุเป้าหมายของเราโดยรับฟัง$routeChangeSuccessเหตุการณ์แทนที่จะวาง$watchบนเส้นทาง ฉันทำงานภายใต้ความเชื่อที่ว่านี่หมายถึงตรรกะควรจะทำงานน้อยลงอย่างที่ฉันคิดว่าดูไฟในแต่ละ$digestรอบ

เรียกใช้โดยส่งผ่านอาร์กิวเมนต์ระดับพา ธ ของคุณในการประกาศคำสั่ง นี่เป็นการระบุสิ่งที่ $ location.path () ปัจจุบันที่คุณต้องการจับคู่กับhrefแอตทริบิวต์ของคุณ

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

ดังนั้นหากแท็บของคุณควรตอบสนองต่อระดับฐานของเส้นทางให้สร้างอาร์กิวเมนต์ '1' ดังนั้นเมื่อ location.path () เป็น "/ home" จะจับคู่กับ "# / home" ในhrefใน หากคุณมีแท็บที่ควรตอบสนองต่อระดับที่สองหรือที่สามหรือที่ 11 ของเส้นทางให้ปรับตามนั้น การแบ่งส่วนนี้จาก 1 หรือมากกว่านั้นจะข้าม '#' สามานย์ใน href ซึ่งจะอยู่ที่ดัชนี 0

ข้อกำหนดเพียงอย่างเดียวคือคุณเรียกใช้<a>เนื่องจากองค์ประกอบถือว่าการมีอยู่ของhrefคุณลักษณะซึ่งจะเปรียบเทียบกับเส้นทางปัจจุบัน อย่างไรก็ตามคุณสามารถปรับเปลี่ยนได้อย่างง่ายดายในการอ่าน / เขียนองค์ประกอบหลักหรือองค์ประกอบย่อยหากคุณต้องการเรียกใช้<li>บางสิ่งบางอย่าง ฉันขุดเพราะคุณสามารถนำมันกลับมาใช้ในบริบทจำนวนมากโดยเพียงแค่การแตกต่างกันอาร์กิวเมนต์ระดับ path หากความลึกในการอ่านถูกสมมติขึ้นในตรรกะคุณจะต้องมีคำสั่งหลายเวอร์ชันเพื่อใช้กับการนำทางหลายส่วน


แก้ไข 3/18/14: แก้ได้ทั่วไปไม่เพียงพอและจะเปิดใช้งานถ้าคุณกำหนดหาเรื่องสำหรับค่า 'activeTab' ที่กลับมาที่undefinedทั้งสองและขององค์ประกอบ$location.path() hrefเพราะ: undefined === undefined. อัปเดตเพื่อแก้ไขเงื่อนไขนั้น

ในขณะที่ทำงานนั้นฉันรู้ว่าควรมีรุ่นที่คุณสามารถประกาศในองค์ประกอบหลักด้วยโครงสร้างแม่แบบดังนี้:

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

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

นอกจากนี้หากคุณต้องการเวอร์ชั่นที่เข้ากันได้กับ bootstrap <li>คุณสามารถไปกับโม ดูแท็บ angular-ui-bootstrapซึ่งฉันคิดว่าออกมาหลังจากโพสต์ต้นฉบับนี้และอาจจะมีการเปิดเผยมากกว่านี้ มันกระชับน้อยกว่าสำหรับเนื้อหาพื้นฐาน แต่มีตัวเลือกเพิ่มเติมให้คุณเช่นแท็บที่ปิดใช้งานและเหตุการณ์ที่ประกาศซึ่งจะเปิดใช้งานและปิดใช้งาน


4
ฉันไม่อยากจะเชื่อเลยว่าไม่มีใครให้คะแนนนี้! นี่คือ 2 เซ็นต์ของฉัน แม้ว่าจะมีข้อผิดพลาดเล็กน้อยในรหัสฉันคิดว่า 'tabLevel' ควรจะเป็น 'activeTab' และสำหรับสไตล์ Bootstrap คุณอาจต้องการเพิ่มคลาส 'active' ให้กับองค์ประกอบ LI แทนองค์ประกอบ A แต่สิ่งนี้ต้องการการเปลี่ยนแปลงเล็กน้อย
David Lin

1
คุณถูกต้องอย่างแน่นอนเกี่ยวกับ activeTab @DavidLin แก้ไข แต่ฉันไม่ได้รักโครงสร้างของ Bootstrap ดังนั้นจึงมีความแตกต่างโดยเจตนา ในความเป็นจริงฉันเริ่มคิดว่านามธรรม abstractions อาจไม่ได้อยู่ในulทั้งหมดและอาจเป็นเพียงชุดของแองเคอร์ห่อด้วยnavองค์ประกอบการจัดกลุ่มหรืออื่น ๆ การจัดการกับตัวกลางของเลเยอร์liนั้นเพิ่มความซับซ้อนโดยไม่มีผลตอบแทนโดยเฉพาะอย่างยิ่งตอนนี้เรามีnavองค์ประกอบตามที่เราต้องการเพื่อให้ชัดเจนว่าเกิดอะไรขึ้น
XML

ง่ายและยอดเยี่ยม ฉันประหลาดใจที่ไม่มีสิ่งนี้ในเชิงมุมสำหรับการตรวจสอบเส้นทางที่คุณอยู่
Intellix

1
เพื่อให้มันทำงานกับ bootstrap3 สิ่งที่คุณต้องทำคือเปลี่ยน `element.addClass (" active ");` เป็น `element.parent ('li'). addClass (" active ");` ฉันคิดว่ามันน่าจะดีกว่า ชื่อแม้ว่าบางสิ่งบางอย่างเช่นis-active-tab จะเข้ามาแทนที่แท็บที่ใช้งานอยู่ซึ่งดูเหมือนว่าจะประกาศว่าแท็บนั้นทำงานอยู่ มิฉะนั้นนี่เป็นคำสั่งที่ดีอย่างจริงจัง ดูการเปลี่ยนแปลงนี้ในคำตอบโดย @domi
boatcoder

ทางออกที่ดีที่สุดในหน้านี้ไม่น่าเชื่อว่ามี upvotes เพียงเล็กน้อย
Karolis

27

@ rob-juurlink ฉันได้ปรับปรุงวิธีการแก้ปัญหาของคุณ:

แทนแต่ละเส้นทางที่ต้องการแท็บที่ใช้งานอยู่ และจำเป็นต้องตั้งค่าแท็บที่ใช้งานอยู่ในแต่ละคอนโทรลเลอร์ฉันจะทำสิ่งนี้:

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

และ HTML มีลักษณะเช่นนี้ แท็บที่ใช้งานอยู่เป็นเพียง URL ที่เกี่ยวข้องกับเส้นทางนั้น สิ่งนี้จะลบความจำเป็นในการเพิ่มโค้ดในแต่ละคอนโทรลเลอร์ (การลากในการพึ่งพาเช่น $ route และ $ rootScope ถ้านี่เป็นเหตุผลเดียวที่พวกมันถูกใช้)

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

ขอบคุณมากสำหรับการปรับเปลี่ยนนี้ ดีมาก. คุณมีคำแนะนำสำหรับการตั้งค่าแท็บที่ใช้งานอยู่เมื่อหน้าโหลดครั้งแรกหรือไม่?
Hairgami_Master

2
ขึ้นอยู่กับสิ่งที่คุณต้องการ โดยปกติแล้วคุณจะมี '/' url เป็นผู้ควบคุมหลักของคุณ วิธีนั้นเมื่อผู้ใช้ไปที่ url ของคุณผู้ใช้จะโหลดคอนโทรลเลอร์นั้นและตั้งค่าแท็บนั้นเป็นใช้งาน ในตัวอย่างข้างต้นฉันไม่มี '/' url ดังนั้นถ้านั่นคือกรณีของคุณเพียงเพิ่ม .other () $ routeProvider $ เมื่อ ('/ dashboard', {templateUrl: 'partials / dashboard.html', ตัวควบคุม: Ctrl1}) เมื่อ ('/ lab', {templateUrl: 'partials / lab.html', คอนโทรลเลอร์: Ctrl2}) มิฉะนั้น ({redirectTo: '/ dashboard'}); ขอให้โชคดี!
ลูคัส

ขอบคุณมาก @Lucas นั่นช่วยได้ เหตุผลที่ฉันต้องเพิ่มสัญลักษณ์ # ในเส้นทางหลักของฉัน - เมื่อ ('# /', {คอนโทรลเลอร์: FormsController, templateUrl: 'partials / dashboard.html'})
Hairgami_Master

ฉันชอบวิธีนี้ มี rootScope และทำทุกอย่างในทุกที่
58

16

คำสั่งเช่นนี้อาจช่วยแก้ปัญหาของคุณได้: 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);
                }
            });
        }

    };

}]);

1
โปรดทราบว่าคุณต้องใช้ $ สังเกตถ้า href มีการแสดงออก: docs.angularjs.org/guide/directive#Attributes ดู fiddle ที่อัพเดทแล้ว: jsfiddle.net/p3ZMR/10
Narretz

14

วิธีที่ง่ายที่สุดที่นี่:

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

ซึ่งเป็น:

ใช้ 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();
    };
}

2
ตกลงโดยไกลที่ง่ายที่สุด
AngeloS

12

ฉันขอแนะนำให้ใช้โมดูล state.uiซึ่งไม่เพียง แต่รองรับหลายมุมมองและซ้อนกัน แต่ยังทำให้งานประเภทนี้ง่ายมาก (โค้ดด้านล่างที่ยกมา):

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

คุ้มค่าในการอ่าน.


4

นี่คืออีกเวอร์ชั่นหนึ่งของการเปลี่ยนแปลง LI ของ XMLillies ด้วยการใช้สตริงการค้นหาแทนที่จะเป็นระดับพา ธ ฉันคิดว่านี่เป็นสิ่งที่ชัดเจนยิ่งขึ้นว่าเกิดอะไรขึ้นกับเคสการใช้งานของฉัน

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 ดูเหมือนว่า:

<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

ฉันพบผู้ประกาศข่าวของ XMLilley ที่ดีที่สุดและปรับตัวได้มากที่สุดและไม่ล่วงล้ำ

อย่างไรก็ตามฉันมีข้อผิดพลาดเล็กน้อย

สำหรับใช้กับ bootstrap nav นี่คือวิธีที่ฉันแก้ไข:

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

ฉันเพิ่ม "if (attrs.href! = undefined)" เพราะฟังก์ชั่นนี้เรียกว่า apprently สองครั้งครั้งที่สองทำให้เกิดข้อผิดพลาด

สำหรับ 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 มันเป็นความผิดของฉันที่ถูกเรียกสองครั้ง ฉันเดาว่า "ไม่จำเป็นต้องมี" if (attrs.href! = undefined) "
domi

3

ตัวอย่าง Bootstrap

หากคุณใช้ Angulars ในการกำหนดเส้นทาง (ngview) คำสั่งนี้สามารถใช้ได้:

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

        }
    };
}]);

สมมติว่ามาร์กอัปของคุณมีลักษณะดังนี้:

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

ฉันชอบที่จะทำเช่นนี้เนื่องจากคุณสามารถตั้งชื่อคลาสที่คุณต้องการในแอตทริบิวต์ของคุณ


2

คุณยังสามารถแทรกตำแหน่งลงในขอบเขตและใช้สิ่งนั้นเพื่อลดสไตล์สำหรับการนำทาง:

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

จากนั้นใช้ในng-class:

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

ไม่ควรเป็น $ root.location.path () ในมาร์กอัปหรือไม่
Irshu

@Irshu: นั่นอาจจะสะอาดกว่า แต่วิธีการข้างต้นก็ใช้ได้กับฉันเช่นกัน
Der Hochstapler

2

วิธีอื่นคือใช้ui-sref-active

คำสั่งทำงานร่วมกับ ui-sref เพื่อเพิ่มคลาสให้กับองค์ประกอบเมื่อสถานะของคำสั่ง ui-sref ที่เกี่ยวข้องนั้นทำงานอยู่และจะลบออกเมื่อไม่มีการใช้งาน กรณีการใช้งานหลักคือการทำให้ลักษณะพิเศษของเมนูนำทางให้ง่ายขึ้นโดยอาศัย ui-sref โดยให้ปุ่มเมนูของรัฐ "ใช้งานอยู่" ปรากฏแตกต่างกันโดยแยกออกจากรายการเมนูที่ไม่ใช้งาน

การใช้งาน:

ui-sref-active = 'class1 class2 class3' - คลาส "class1", "class2" และ "class3" จะถูกเพิ่มเข้าไปในองค์ประกอบคำสั่งเมื่อสถานะของ ui-sref ที่เกี่ยวข้องนั้นเปิดใช้งานและลบออกเมื่อไม่ได้ใช้งาน

ตัวอย่าง:
รับแม่แบบต่อไปนี้

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

เมื่อสถานะแอปเป็น "app.user" และมีพารามิเตอร์สถานะ "ผู้ใช้" ที่มีค่า "bilbobaggins" HTML ที่ได้จะปรากฏเป็น

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

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

ใช้คำสั่ง ui-sref-opts เพื่อส่งตัวเลือกไปยัง $ state.go () ตัวอย่าง:

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

ขอบคุณ มันมีประโยชน์จริง ๆ เมื่อทำงานในกรอบไอออนิก!
Avijit Gupta

1

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

ตัวอย่าง 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

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/


ฉันชอบวิธีการที่ขับเคลื่อนด้วยข้อมูลไปยังรายการลิงก์ และบางคนอาจเลือกที่จะย้ายอาเรย์ของลิงค์ไปยังบริการ / โรงงาน
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();
    };
  });

และใช้ด้านล่างในเทมเพลต:

<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

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

# 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

มันไม่ได้ขึ้นอยู่กับ URL และมันง่ายมากที่จะตั้งค่าสำหรับหน้าย่อยใด ๆ เป็นต้น


0

ฉันจำไม่ได้ว่าฉันพบวิธีนี้ที่ไหน แต่มันค่อนข้างง่ายและใช้งานได้ดี

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

หากคุณใช้ ngRoute (สำหรับการกำหนดเส้นทาง) แอปพลิเคชันของคุณจะมีการกำหนดค่าต่ำกว่า

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

ตอนนี้เพียงเพิ่มตัวควบคุมในการกำหนดค่านี้เหมือนด้านล่าง

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

ดังที่คุณได้กล่าวถึงแท็บที่ใช้งานในการกำหนดค่าของคุณตอนนี้คุณเพียงแค่ต้องเพิ่มคลาสที่ใช้งานใน<li>หรือ<a>แท็กของคุณ ชอบ,

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

ซึ่งหมายความว่าเมื่อใดก็ตามที่ผู้ใช้คลิกที่หน้าเพจสิ่งนี้จะระบุแท็บปัจจุบันโดยอัตโนมัติและใช้คลาส css ที่ใช้งานอยู่

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


-3

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

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