Каков наилучший способ условно применить класс? - PullRequest
1163 голосов
/ 17 октября 2011

Допустим, у вас есть массив, который отображается в ul с li для каждого элемента и свойством контроллера, называемым selectedIndex.Как лучше всего добавить класс в li с индексом selectedIndex в AngularJS?

В настоящее время я дублирую (вручную) код li и добавляю класс в один изтеги li и использование ng-show и ng-hide для отображения только одного li на индекс.

Ответы [ 22 ]

1378 голосов
/ 29 ноября 2011

Если вы не хотите помещать имена классов CSS в Controller, как я, вот старый прием, который я использую с дней до v1. Мы можем написать выражение, которое оценивает непосредственно имя класса selected , никаких пользовательских директив не требуется:

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

Обратите внимание на старый синтаксис с двоеточием.

Существует также новый лучший способ условного применения классов, например:

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

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

Однако эти пути функционально не равны. Вот пример:

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

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

434 голосов
/ 28 августа 2012

ng-class поддерживает выражение, которое должно принимать значение

  1. Строка имен классов, разделенных пробелами, или
  2. Массив имен классовили
  3. Карта / объект с именами классов для логических значений.

Итак, используя форму 3), мы можем просто написать

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

См. Также Как условно применять стили CSS в AngularJS? для более широкого ответа.


Обновление : В Angular 1.1.5 добавлена ​​поддержка троичного оператора , поэтому, если эта конструкция вам более знакома:

ng-class="($index==selectedIndex) ? 'selected' : ''"
159 голосов
/ 27 сентября 2013

Мой любимый метод - использование троичного выражения.

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

Примечание: Если вы используете более старую версию Angular, вы должны использовать ее вместо

ng-class="condition && 'trueClass' || 'falseClass'"
54 голосов
/ 27 сентября 2012

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

<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

46 голосов
/ 17 октября 2011

Вот гораздо более простое решение:

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>
26 голосов
/ 26 июля 2012

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

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

Он принимает один аргумент, который является либо 2-элементным массивом, либо строкой, которая превращается в массив, к которому добавляется пустая строка в качестве второго элемента:

<li ng-repeat="item in products | filter:search | orderBy:orderProp |
  page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
  ...
</li>
21 голосов
/ 04 сентября 2012

Если вы хотите пойти дальше бинарной оценки и не использовать свой 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>
17 голосов
/ 28 мая 2014

Я недавно сделал, что делал это:

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

Значение isShowing - это значение, которое находится на моем контроллере, которое переключается нажатием кнопки и частей междуодиночные скобки - это классы, которые я создал в своем файле css.

РЕДАКТИРОВАТЬ: Я также хотел бы добавить, что для codeschool.com есть бесплатный курс, спонсируемый Google на AngularJS, который охватывает все эти вещи, а затем некоторые,Вам не нужно ничего платить, просто зарегистрируйтесь и приступайте!Удачи всем вам!

15 голосов
/ 23 мая 2013

Тернарный оператор только что был добавлен в угловой анализатор в 1.1.5 .

Итак, самый простой способ сделать это сейчас:

ng:class="($index==selectedIndex)? 'selected' : ''"
11 голосов
/ 04 ноября 2015

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

enter image description here

<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, если пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...