Вопрос: Каков наилучший способ условного применения класса?


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

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


1125


источник


Ответы:


Если вы не хотите помещать имена классов CSS в Controller, как я, это старый трюк, который я использую с пре-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 из кода контроллера.


1361



нг-класс поддерживает выражение, которое должно

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

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

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

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


Обновить : Угловая 1.1.5 добавила поддержку тернарный оператор , поэтому, если эта конструкция вам более знакома:

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

431



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

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

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

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

156



I'll add to this, because some of these answers seem out of date. Here's how I do it:

<class="ng-class:isSelected">

Where 'isSelected' is a javascript variable defined within the scoped angular controller.


To more specifically address your question, here's how you might generate a list with that:





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": ""}
    ]
}


See: http://jsfiddle.net/tTfWM/

See: http://docs.angularjs.org/api/ng.directive:ngClass


53



Here is a much simpler solution:

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>


46



I faced a similar problem recently and decided to just create a conditional filter:

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

It takes a single argument, which is either a 2-element array or a string, which gets turned into an array that is appended an empty string as the second element:

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

26



If you want to go beyond binary evaluation and keep your CSS out of your controller you can implement a simple filter that evaluates the input against a map object:

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

This allows you to write your markup like this:

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

21



Ternary operator has just been added to angular parser in 1.1.5.

So the simplest way to do this is now :

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

15



The was I recently did that was doing this:

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

The isShowing value is a value that is located on my controller that gets toggled with the click of a button and the parts between the single parenthesis are classes I created in my css file.

EDIT: I would also like to add that codeschool.com has a free course that is sponsored by google on AngularJS that goes over all of this stuff and then some. There is no need to pay for anything, just signup for an account and get going! Best of luck to you all!


15



We can make a function to manage return class with condition

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>

And then

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

You can refer to full code page at ng-class if example


11



I am new to Angular but have found this to solve my issue:

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

This will conditionally apply a class based on a var. It starts off with a icon-download as a default, the using ng-class, I check the status of showDetails if true/false and apply class icon-upload. Its working great.

Hope it helps.


9



Популярные вопросы: