Как установить загрузочный класс Navbar с помощью Angular JS?

301

Если у меня есть navbar в bootstrap с элементами

Home | About | Contact

Как установить активный класс для каждого элемента меню, когда они активны? То есть, как я могу установить class="active", когда маршрут angular находится в

  • #/ для дома
  • #/about для страницы about
  • #/contact для контактной страницы
Показать ещё 2 комментария
Теги:
angularjs-directive
navbar

26 ответов

620
Лучший ответ

Очень элегантный способ - использовать 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();
    };
}
  • 0
    Может ли это быть помещено в директиву заголовка?
  • 1
    Да, конечно, может! Вот собственно так и пользуюсь сам :)
Показать ещё 22 комментария
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
    мне нравится это лучше, чем принятый ответ, потому что нет никакого дублирования данных конфигурации, то есть сами маршруты остаются в одном месте, и это просто работает ..
  • 1
    работал для меня с использованием scope. $ watch ("$ routeChangeSuccess", function () {.... вместо scope. $ on ("$ routeChangeSuccess", function () {....
Показать ещё 2 комментария
37

Вы можете взглянуть на 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');
          }

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

Чтобы использовать эту директиву:

  • Скачать AngularStrap из http://mgcrea.github.io/angular-strap/

  • Включите script на свою страницу после загрузки bootstrap.js:
    <script src="lib/angular-strap.js"></script>

  • Добавьте директивы в свой модуль:
    angular.module('myApp', ['$strap.directives'])

  • Добавить директиву на ваш навигатор:
    <div class="navbar" bs-navbar>

  • Добавить регулярные выражения для каждого элемента навигации:
    <li data-match-route="/about"><a href="#/about">About</a></li>

  • 1
    Благодарю. Это помогло мне исправить мою собственную директиву (для меня не хватало понимания scope.$watch )
  • 0
    Почему переменная element передается в селектор jquery? $('...', element)
Показать ещё 2 комментария
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, чтобы она возвращала true / false вместо самого имени класса.
  • 0
    Я скопировал все, как в вашем примере, и у меня $ location.path () не сработал ... переключился на $ location.url (), и это сработало!
11

Если вы работаете с Angular router, директива RouterLinkActive может использоваться очень элегантно:

<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 или его родителем)
  • 3
    Примечание: если вы используете / качестве домашней страницы, routerLinkActive будет считать его активным для любого URL, начинающегося с / , например /foo/ , /foo/bar и т. Д. Для точного соответствия вам необходимо routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}" .
8

Прежде всего, эта проблема может быть решена многими способами. Этот способ может быть не самым элегантным, но он работает нормально.

Вот простое решение, которое вы можете добавить в любой проект. Вы можете просто добавить "pageKey" или другое свойство при настройке маршрута, который вы можете использовать для отключения. Кроме того, вы можете реализовать прослушиватель метода $routeChangeSuccess объекта $route для прослушивания успешного завершения изменения маршрута.

Когда ваш обработчик срабатывает, вы получаете ключ страницы и используете этот ключ для поиска элементов, которые должны быть "ACTIVE" для этой страницы, и вы применяете класс ACTIVE.

Имейте в виду, что вам нужен способ сделать ВСЕ элементы "IN ACTIVE". Как вы можете видеть, я использую класс .pageKey для своих навигационных элементов, чтобы отключить их, и я использую .pageKey_ {PAGEKEY} для индивидуального включения их. Переключение всех их в неактивные, будет считаться наивным, потенциально вы получите лучшую производительность, используя предыдущий маршрут, чтобы сделать только активные элементы неактивными, или вы можете изменить селектор jquery, чтобы отображать только активные элементы, которые будут считаться неактивными. Использование jquery для выбора всех активных элементов, вероятно, является лучшим решением, поскольку оно обеспечивает очистку всего текущего маршрута в случае любых ошибок css, которые могли присутствовать на предыдущем маршруте.

Это означало бы изменение этой строки кода:

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

к этому

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

Вот пример кода:

Учитывая загрузочную навигационную панель

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

И модуль и контроллер angular, как показано ниже:

<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>
  • 0
    Вам нужно прокрутить вправо, чтобы увидеть значения pageKey на маршрутах, это ключ ко всему этому решению.
  • 16
    Это может работать, но противоречит общему совету для приложений Angular.js: в Angular вы должны воздерживаться от работы с DOM с помощью jQuery; если вам нужно дотронуться до DOM, напишите директиву.
Показать ещё 1 комментарий
7

Фактически вы можете использовать директиву angular -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 для управления частичным/вложенные представления.

  • 0
    Подход ui-route очень соблазнителен, но до сих пор мне не удалось заставить его работать над проектом, сгенерированным угловым генератором Йомана.
  • 0
    @gabuzo: Вы устанавливали angular-ui-utils через беседку?
6

Я считаю, что все эти ответы немного сложнее для меня, извините. Поэтому я создал небольшую директиву, которая должна работать на основе каждой панели:

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>
  • 0
    Ваш метод работает только после нажатия на ссылку в навигационной панели. Если вы начинаете с URL-адреса «Foo», изначально будет выбран «Домой». например, запуск с локального хоста: 9000 / # / contact заставляет Дом отображаться выбранным в навигационной панели.
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

Если вы используете ui-router, следующий пример должен удовлетворять вашим потребностям на основе комментария @DanPantry принятого ответа без добавления какого-либо контроллера -side код:

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

Подробнее об этом можно узнать в docs.

  • 0
    идеально! безусловно, самое чистое решение
  • 0
    Просто самое лучшее решение. кто не использует ui.router !
4

Вы можете достичь этого с условным выражением в выражении angular, например:

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

Как я уже сказал, я нахожу директиву angular более "правильной" способ сделать это, хотя аутсорсинг этой мини-логики может несколько загрязнить вашу базу кода.

Я использую условные обозначения для GUI-стиля каждый раз в процессе разработки, потому что это немного быстрее, чем создание директив. Я не мог сказать вам экземпляр, в котором они на самом деле оставались в базе кода надолго. В конце концов, я либо превращу его в директиву, либо найду лучший способ решить проблему.

3

Вот, что я беру на себя. Немного сочетания ответов, найденных на этом посту. У меня был немного другой случай, поэтому мое решение включает в себя разделение меню на его собственный шаблон, который будет использоваться в определении Ojbect директивы, а затем добавьте мою навигационную панель на нужную мне страницу. В принципе, у меня была страница входа, в которую я не хотел включать мое меню, поэтому я использовал ngInclude и вставлял эту директиву при входе в систему:

ДИРЕКТИВА:

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;

        }
    }
 }
});

ДИРЕКТИВНЫЙ ШАБЛОН (templates/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, ВКЛЮЧАЯ ДИРЕКТИВУ

<comp-navbar/>

Надеюсь, что это поможет

  • 1
    Функцию можно сократить до $ scope.isActive = function (viewLocation) {return viewLocation === $ location.path (); };
3

Если вы предпочитаете не использовать AngularStrap, то эта директива должна делать трюк!. Это модификация https://stackoverflow.com/questions/16199418/how-to-set-bootstrap-navbar-active-class-with-angular-js.

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

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

Расширение myl-ответа, мне нужно было это для обработки такой структуры.

-index

-СОБЫТИЯ < -активное
--- событий список
--- событий редактировать
--- event-map < -clicked

-places
--- Места список
--- место, редактировать
--- место-карта

поэтому вместо сопоставления мне пришлось использовать indexOf, чтобы проверить дочерние ссылки, которые отформатированы в соответствии с условием. Итак, для "событий":

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

Каждый раз, когда вы нажимаете на ссылку, объект переключателя заменяется новым объектом, в котором истинным является только правильное свойство объекта переключателя. Неопределенные свойства будут оцениваться как ложные, и поэтому элементам, которые зависят от них, не будет назначен активный класс.

1

Благодаря @Pylinux. Я использовал его технику и также модифицировал ее для поддержки "одного" уровня выпадающего меню (sub ul/li), так как это то, что мне было нужно. См. Его в действии в ссылке скрипта ниже.

Обновлено Fiddle на основе ответа pylinux - http://jsfiddle.net/abhatia/en4qxw6g/

Я сделал следующие три изменения, чтобы поддержать одноуровневое выпадающее меню:
1. Добавлено значение класса dd (выпадающее меню) для элемента" a" под ли, которое должно иметь подменю 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

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>
  • 0
    Это не работает - это не добавляет текущий класс в DOM
1

В сочетании с ответом @Olivier AngularStrap я также выполнил ответ kevinknelson: https://github.com/twbs/bootstrap/issues/9013.

В основном, навигационная панель Bootstrap3 не была предназначена для одностраничного приложения (например, Angular), и, таким образом, меню, когда на маленьком экране не сжималось при щелчке.

0

Просто вам нужно добавить требуемый класс active с требуемым цветовым кодом.

Пример: ng-class="{'active': currentNavSelected}" ng-click="setNav"

0

Здесь другое решение для всех, кто может быть заинтересован. Преимущество этого заключается в том, что он имеет меньше зависимостей. Черт возьми, он работает и без веб-сервера. Так что это полностью клиентская сторона.

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>

Пояснение:

Здесь мы динамически генерируем связи из модели углов, используя директиву ng-repeat. Магия происходит с методами selectTab() и getTabClass(), определенными в контроллере для этой навигационной панели, представленной ниже.

Контроллер:

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. Если true, он возвращает "active" else возвращает "", который применяется как имя класса в директиве ng-class. Затем любой CSS, который вы применили к классу active, будет применен к выбранной вкладке.

  • 0
    Что происходит, когда я перехожу на другую вкладку любым другим способом?
  • 0
    Что вы имеете в виду?
Показать ещё 2 комментария
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

Просто чтобы добавить свои два цента в дебаты, я создал чистый angular модуль (без jquery), и он также будет работать с хеш-адресами, содержащими данные. (i.g. #/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/# или просто example.com). должен иметь не менее example.com/#/ или просто example.com#/. Но это происходит автоматически с ngResource и т.п.

  • 0
    Это просто противно. Причина использования Angular для простоты.
0

Я предлагаю использовать директиву по ссылке. Здесь - скрипка.

Но еще не совершенен. Следите за хэш-бэгами;)

Вот директива 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

Это сделало трюк для меня:

  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 (также работает с angular), чтобы добавить класс active

$('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

Вы также можете использовать эту директиву с активной ссылкой https://stackoverflow.com/questions/12592472/how-to-highlight-a-current-menu-item

Parent li получит активный класс, если совпадение /url:

<li>
    <a href="#!/url" active-link active-link-parent>
</li>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню