Який найкращий спосіб умовно застосувати клас?


1183

Скажімо, у вас є масив, який відображається в а ul, liдля кожного елемента та властивості контролера, що викликається selectedIndex. Що було б найкращим способом додати клас до liіндексу selectedIndexв AngularJS?

Наразі я дублюю (вручну) liкод і додаю клас до одного з liтегів, використовую ng-showта ng-hideпоказую лише один liна індекс.


2
Відповіді на це запитання показують, що в шаблонах більше, ніж {{varname}}. Де я можу знайти документацію щодо того, що ще існує для шаблонів, таких як потрійний оператор у декількох різних формах? docs.angularjs.org/guide/templates , схоже, не пояснює, що шаблони пропонують в умові тощо, окрім {{varname.fieldname}}.
Крістос Хейвард

це настільки корисно для мене, сподіваюся, воно буде працювати для вас tech-blog.maddyzone.com/javascript/…
Rituraj ratan

Відповіді:


1384

Якщо ви не хочете вводити імена класів CSS в Controller, як я, ось старий трюк, який я використовую з часу pre-v1 днів. Ми можемо написати вираз, який оцінює безпосередньо вибране ім'я класу , не потрібні спеціальні директиви:

ng:class="{true:'selected', false:''}[$index==selectedIndex]"

Зверніть увагу на старий синтаксис з двокрапкою.

Існує також новий кращий спосіб застосування класів умовно, наприклад:

ng-class="{selected: $index==selectedIndex}"

Angular тепер підтримує вирази, які повертають об'єкт. Кожне властивість (ім'я) цього об'єкта зараз розглядається як ім'я класу і застосовується залежно від його значення.

Однак ці способи функціонально не рівні. Ось приклад:

ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"

Таким чином, ми могли б повторно використовувати існуючі класи CSS, в основному зіставивши властивість моделі з назвою класу і в той же час утримати класи CSS від коду контролера.


33
ОП, це може бути гіршим способом виразити потрійного оператора, якого я коли-небудь бачив. Ви розглядали ($index==selectedIndex) ? 'selected' : ''?
Мальволіо

17
@Malvolio AFAIR, потрійний оператор не працював у кутових виразах у v0.9.x. Це більш-менш вимикач.
orcun

36
ng-class (станом на 19.01.2012) тепер підтримує вираз, який повинен оцінювати або 1) рядок з іменами класів з обмеженим пробілом, або 2) та масив назв класів, або 3) карту / об'єкт класу імена до булевих значень. Отже, використовуючи 3): ng-class = "{selected: $ index == selectedIndex}"
Марк Rajcok

2
Дякую @Mark, BTW тепер, коли я перевірив, можу сказати, що цей метод працює у v1. Він все ще корисний у деяких випадках. Зауважте, що імена властивостей об’єктів (ключів) не обов'язково є істинними або хибними, це може бути все, що ви хочете зіставити з ім'ям класу.
orcun

6
Я просто хочу додати, у мене виникла проблема, оскільки я використовував синтаксис, як {classname: '$index === selectedIndex'} і він не працював. Коли я все розсунув і використав == замість ===, це спрацювало. {classname: '$index==selectedIndex'}
Лукас

437

ng-class підтримує вираз, який повинен оцінювати будь-якому

  1. Рядок імен класів з обмеженим пробілом, або
  2. Масив назв класів, або
  3. Карта / об'єкт імен класів до булевих значень.

Отже, використовуючи форму 3) ми можемо просто написати

ng-class="{'selected': $index==selectedIndex}"

Див. Також Як я умовно застосувати стилі CSS в AngularJS? для більш широкої відповіді.


Оновлення : Angular 1.1.5 додав підтримку потрійного оператора , тож якщо ця конструкція вам більше знайома:

ng-class="($index==selectedIndex) ? 'selected' : ''"

2
+1 для потрійних операторів (і мені зараз потрібен один), але 1.1. * - це «нестабільний випуск», коли API може змінюватися без попереднього повідомлення - на час введення тексту. 1.0. * Стабільний, тому мені буде зручніше працювати з цим проектом, який буде впроваджений наступного тижня протягом 6 місяців.
Дейв Еверітт

1
ng-class="{'selected': $index==selectedIndex}"працює для мене
knuhol

160

Мій улюблений метод - це використання потрійного виразу.

ng-class="condition ? 'trueClass' : 'falseClass'"

Примітка. Якщо ви використовуєте старішу версію Angular, ви повинні використовувати це замість цього,

ng-class="condition && 'trueClass' || 'falseClass'"

2
Це допомогло мені писати цей вислів: ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}". Не вдалося з'ясувати іншого способу.
dduft

Я дійсно не знаходжу, чому мій масштабний булевий modalFlag не оновлюється - ng-class = "{'закрито': modalFlag, 'open':! ModalFlag}" Я намагаюся додати закритий або відкритий, залежно від зміненої області / булевої " - якщо хтось може допомогти, я був би дуже вдячний - дякую вам.
приземлився

Це було представлено у версії 1.5. github.com/angular/angular.js/commit/…
Mubashir Koul

55

Я додам до цього, бо деякі з цих відповідей здаються застарілими. Ось як я це роблю:

<class="ng-class:isSelected">

Де 'isSelected' - це змінна javascript, визначена в межах діапазону кутового контролера.


Щоб детальніше вирішити своє питання, ось як можна створити список із цим:

HTML

<div ng-controller="ListCtrl">  
    <li class="ng-class:item.isSelected" ng-repeat="item in list">   
       {{item.name}}
    </li>  
</div>


JS

function ListCtrl($scope) {    
    $scope.list = [  
        {"name": "Item 1", "isSelected": "active"},  
        {"name": "Item 2", "isSelected": ""}
    ]
}


Дивіться: http://jsfiddle.net/tTfWM/

Дивіться: http://docs.angularjs.org/api/ng.directive:ngClass


Що різниться між class = "ng-class: item.isSelected" та ng-class = "item.isSelected"
zloctb

Цікаво про використання ng-class:classNamevs просто за допомогою class="{{className}}"?
Рой

48

Ось набагато простіше рішення:

function MyControl($scope){
    $scope.values = ["a","b","c","d","e","f"];
    $scope.selectedIndex = -1;
    
    $scope.toggleSelect = function(ind){
        if( ind === $scope.selectedIndex ){
            $scope.selectedIndex = -1;
        } else{
            $scope.selectedIndex = ind;
        }
    }
    
    $scope.getClass = function(ind){
        if( ind === $scope.selectedIndex ){
            return "selected";
        } else{
            return "";
        }
    }
       
    $scope.getButtonLabel = function(ind){
        if( ind === $scope.selectedIndex ){
            return "Deselect";
        } else{
            return "Select";
        }
    }
}
.selected {
    color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app ng-controller="MyControl">
    <ul>
        <li ng-class="getClass($index)" ng-repeat="value in values" >{{value}} <button ng-click="toggleSelect($index)">{{getButtonLabel($index)}}</button></li>
    </ul>
    <p>Selected: {{selectedIndex}}</p>
</div>


74
Я настійно рекомендую не захищати ваш контролер від CSS. Це шлях, яким ви не хочете спуститися.
левіафан

1
Назви класів належать до шаблону
Casey

5
У якийсь момент jsfiddle може пропустити оплату рахунків або вибрати перехід на інший домен, або відповідальних людей вбиває автобус (див. Також Bus Factor). Тож я можу попросити вас пояснити, що робить ця скрипка у межах вашої відповіді? Це також є канонічним щодо переповнення стека.
Себастьян Мах

27

Нещодавно я зіткнувся з подібною проблемою і вирішив просто створити умовний фільтр:

  angular.module('myFilters', []).
    /**
     * "if" filter
     * Simple filter useful for conditionally applying CSS classes and decouple
     * view from controller 
     */
    filter('if', function() {
      return function(input, value) {
        if (typeof(input) === 'string') {
          input = [input, ''];
        }
        return value? input[0] : input[1];
      };
    });

Він займає один аргумент, який є або двоелементним масивом, або рядком, який перетворюється на масив, до якого додається порожня рядок як другий елемент:

<li ng-repeat="item in products | filter:search | orderBy:orderProp |
  page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
  ...
</li>

1
мені щойно я створив для прикладу фільтра yesNo (), що повертає класи "так" або "ні" відповідно до булевого значення 1 o 0:filter('yesNo', function() { return function(input) { // info('yesNo('+ input +')'); switch(input){ case '1': return ' yes '; break; default: return ' no '; break; } } });
svassr

1
ng-class може обробляти карту / об'єкт імен класів до булевих значень, тому ви можете просто написати наступне: ng-class = "{так: some_boolean_expression, ні: some_other_boolean_expression}" Наприклад, ng-class = "{так: введення , ні
:!

21

Якщо ви хочете вийти за межі двійкового оцінювання і не утримувати CSS від свого контролера, ви можете застосувати простий фільтр, який оцінює вхід по об'єкту карти:

angular.module('myApp.filters, [])
  .filter('switch', function () { 
      return function (input, map) {
          return map[input] || '';
      }; 
  });

Це дозволяє записати свою розмітку так:

<div ng-class="muppets.star|switch:{'Kermit':'green', 'Miss Piggy': 'pink', 'Animal': 'loud'}">
    ...
</div>

Привіт @ Joe, будь-які ідеї, як обробити нульові значення? Якщо я пропустять нуль у введенні, він не буде відображати свій клас ...
dalcam

1
@ user1191559 - ви можете на карті навести "елемент" за замовчуванням, а потім повернути це значення, якщо "input" недійсне.
Джо Стіл

17

Я це нещодавно робив:

<input type="password"  placeholder="Enter your password"
ng-class="{true: 'form-control isActive', false: 'isNotActive'}[isShowing]">

isShowingЗначення являє собою значення , яке знаходиться на моєму контролері , який отримує перемикається з клацанням кнопки і частини між одинарними дужками класами я створив в моєму файлі CSS.

EDIT: Я також хотів би додати, що codechool.com має безкоштовний курс, який спонсорує google на AngularJS, який переглядає всі ці речі, а потім і деякі. Не потрібно нічого платити, просто підпишіться на рахунок і вирушайте! Удачі вам усім!


Чи можете ви надати тут загадку чи більше коду? Є чи isShowingмасив в контролері тоді?
Кайл Пеннелл

Я здогадуюсь булевий
Мірко

15

Термінальний оператор щойно доданий до кутового аналізатора в 1.1.5 .

Тож найпростіший спосіб зробити це зараз:

ng:class="($index==selectedIndex)? 'selected' : ''"

Крім того : class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';".
пітер

11

Ми можемо створити функцію управління класом повернення з умовою

введіть тут опис зображення

<script>
    angular.module('myapp', [])
            .controller('ExampleController', ['$scope', function ($scope) {
                $scope.MyColors = ['It is Red', 'It is Yellow', 'It is Blue', 'It is Green', 'It is Gray'];
                $scope.getClass = function (strValue) {
                    switch(strValue) {
                        case "It is Red":return "Red";break;
                        case "It is Yellow":return "Yellow";break;
                        case "It is Blue":return "Blue";break;
                        case "It is Green":return "Green";break;
                        case "It is Gray":return "Gray";break;
                    }
                }
        }]);
</script>

І потім

<body ng-app="myapp" ng-controller="ExampleController">

<h2>AngularJS ng-class if example</h2>
<ul >
    <li ng-repeat="icolor in MyColors" >
        <p ng-class="[getClass(icolor), 'b']">{{icolor}}</p>
    </li>
</ul>
<hr/>
<p>Other way using : ng-class="{'class1' : expression1, 'class2' : expression2,'class3':expression2,...}"</p>
<ul>
    <li ng-repeat="icolor in MyColors">
        <p ng-class="{'Red':icolor=='It is Red','Yellow':icolor=='It is Yellow','Blue':icolor=='It is Blue','Green':icolor=='It is Green','Gray':icolor=='It is Gray'}" class="b">{{icolor}}</p>
    </li>
</ul>

Ви можете, наприклад, звернутися до повної кодової сторінки в ng-class


9

Я новачок у Angular, але знайшов це, щоб вирішити мою проблему:

<i class="icon-download" ng-click="showDetails = ! showDetails" ng-class="{'icon-upload': showDetails}"></i>

Це умовно застосовується клас на основі var. Він починається з завантаження значків за замовчуванням, використовуючи ng-клас, я перевіряю стан showDetailsif true/falseі застосовую клас icon-upload . Це працює чудово.

Сподіваюся, це допомагає.


9

Це працює як шарм;)

<ul class="nav nav-pills" ng-init="selectedType = 'return'">
    <li role="presentation" ng-class="{'active':selectedType === 'return'}"
        ng-click="selectedType = 'return'"><a href="#return">return

    </a></li>
    <li role="presentation" ng-class="{'active':selectedType === 'oneway'}"
        ng-click="selectedType = 'oneway'"><a href="#oneway">oneway
    </a></li>
</ul>

5

Ймовірно, це забуде до забуття, але ось як я використовував потрійні оператори 1.1.5 для перемикання класів залежно від того, чи є рядок у таблиці першим, середнім чи останнім - за винятком випадків, якщо в таблиці є лише один рядок:

<span class="attribute-row" ng-class="(restaurant.Attributes.length === 1) || ($first ? 'attribute-first-row': false || $middle ? 'attribute-middle-row': false || $last ? 'attribute-last-row': false)">
</span>

5

Це в моїй роботі кілька умовно судження:

<li ng-repeat='eOption in exam.examOptions' ng-class="exam.examTitle.ANSWER_COM==exam.examTitle.RIGHT_ANSWER?(eOption.eoSequence==exam.examTitle.ANSWER_COM?'right':''):eOption.eoSequence==exam.examTitle.ANSWER_COM?'wrong':eOption.eoSequence==exam.examTitle.RIGHT_ANSWER?'right':''">
  <strong>{{eOption.eoSequence}}</strong> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
  <span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
</li>

4

Ось ще один варіант, який добре працює, коли ng-клас неможливо використовувати (наприклад, під час стилізації SVG):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

(Я думаю, що вам потрібно мати останній нестабільний Angular, щоб використовувати ng-attr-, я зараз на 1.1.4)


4

добре, я б запропонував вам перевірити стан у вашому контролері з функцією, що повертає істину чи помилку .

<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>

і у своєму контролері перевірити стан

$scope.getTodayForHighLight = function(today, date){
return (today == date);
}

4

частковий

  <div class="col-md-4 text-right">
      <a ng-class="campaign_range === 'thismonth' ? 'btn btn-blue' :  'btn btn-link'" href="#" ng-click='change_range("thismonth")'>This Month</a>
      <a ng-class="campaign_range === 'all' ? 'btn btn-blue' :  'btn btn-link'" href="#" ng-click='change_range("all")'>All Time</a>
  </div>

контролер

  $scope.campaign_range = "all";
  $scope.change_range = function(range) { 
        if (range === "all")
        {
            $scope.campaign_range = "all"
        }
        else
        {  
            $scope.campaign_range = "thismonth"
        }
  };

3

Якщо ви використовуєте angular pre v1.1.5 (тобто немає потрійного оператора) і все ще хочете еквівалентний спосіб встановити значення в обох умовах, ви можете зробити щось подібне:

ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"

3

Якщо у вас є загальний клас, який застосовується до багатьох елементів, ви можете створити власну директиву, яка додасть такий клас, як ng-show / ng-hid.

Ця директива додасть класу "активний" кнопку, якщо її натиснути

module.directive('ngActive',  ['$animate', function($animate) {
  return function(scope, element, attr) {
    scope.$watch(attr.ngActive, function ngActiveWatchAction(value){
      $animate[value ? 'addClass' : 'removeClass'](element, 'active');
    });
  };
}]);

Більше інформації


3

Просто додавши щось, що працювало для мене сьогодні, після довгого пошуку ...

<div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">

Сподіваємось, це сприяє вашому успішному розвитку.

=)

Недокументований синтаксис виразів: Велике посилання на веб-сайт ... =)


Перевірте прийняту відповідь. Він робить те саме і дає більше прикладів.
поважаю TheCode

3

Перевірте це .

Сумнівна if|elseзаява AngularJS !!!
Коли я почав використовувати Angularjs, я трохи здивувався, що не зміг знайти твердження if / else.

Тож я працював над проектом, і я помітив, що при використанні оператора if / else стан показується під час завантаження. Ви можете скористатися ng-плащем, щоб виправити це.

<div class="ng-cloak">
 <p ng-show="statement">Show this line</span>
 <p ng-hide="statement">Show this line instead</span>
</div>

.ng-cloak { display: none }

Дякую, amadou


0

Ви можете використовувати цей пакет npm. Він обробляє все і має параметри для статичних та умовних класів на основі змінної чи функції.

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames({class1: true, class2 : false})} />
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.