Question Quel est le meilleur moyen d'appliquer une classe de manière conditionnelle?


Disons que vous avez un tableau qui est rendu dans un ul avec un li pour chaque élément et une propriété sur le contrôleur appelé selectedIndex. Quel serait le meilleur moyen d'ajouter une classe à la li avec l'index selectedIndex dans AngularJS?

Je suis en train de dupliquer (à la main) le li code et en ajoutant la classe à l'un des li tags et en utilisant ng-show et ng-hide pour montrer seulement un li par index.


1132
2017-10-17 10:49


origine


Réponses:


Si vous ne voulez pas mettre les noms de classes CSS dans Controller comme je le fais, voici un vieux truc que j'utilise depuis les jours précédant v1. Nous pouvons écrire une expression qui évalue directement un nom de classe choisi, aucune directive personnalisée n'est nécessaire:

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

S'il vous plaît noter l'ancienne syntaxe avec deux points. 

Il y a aussi une nouvelle meilleure façon d'appliquer des classes conditionnellement, comme:

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

Angulaire prend désormais en charge les expressions qui renvoient un objet. Chaque propriété (nom) de cet objet est maintenant considérée comme un nom de classe et est appliquée en fonction de sa valeur.

Cependant, ces moyens ne sont pas fonctionnellement égaux. Voici un exemple:

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

Nous pouvons donc réutiliser les classes CSS existantes en mappant essentiellement une propriété de modèle à un nom de classe et en même temps garder les classes CSS hors du code du contrôleur.


1367
2017-11-29 11:17



ng-classe prend en charge une expression qui doit évaluer soit

  1. Une chaîne de noms de classes délimitées par des espaces, ou
  2. Un tableau de noms de classe, ou
  3. Une carte / objet de noms de classe à des valeurs booléennes.

Donc, en utilisant le formulaire 3), nous pouvons simplement écrire

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

Voir également Comment est-ce que j'applique conditionnellement les styles CSS dans AngularJS? pour une réponse plus large.


Mettre à jour: Angular 1.1.5 a ajouté un support pour un opérateur ternaire, donc si cette construction vous est plus familière:

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

432
2017-08-28 01:13



Ma méthode préférée est l'utilisation de l'expression ternaire.

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

Remarque: Si vous utilisez une version plus ancienne d'Angular, vous devriez l'utiliser à la place,

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

155
2017-09-27 13:39



Je vais ajouter à cela, parce que certaines de ces réponses semblent démodées. Voici comment je le fais:

<class="ng-class:isSelected">

Où 'isSelected' est une variable javascript définie dans le contrôleur angulaire scoped.


Pour répondre plus précisément à votre question, voici comment générer une liste avec:

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


Voir: http://jsfiddle.net/tTfWM/

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


53
2017-09-27 02:01



Voici une solution beaucoup plus simple:

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
2017-10-17 13:55



J'ai récemment fait face à un problème similaire et j'ai décidé de créer un filtre conditionnel:

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

Il prend un seul argument, qui est un tableau à 2 éléments ou une chaîne, qui devient un tableau auquel est ajoutée une chaîne vide en tant que second élément:

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

26
2017-07-26 07:53



Si vous voulez aller au-delà de l'évaluation binaire et garder votre CSS hors de votre contrôleur, vous pouvez implémenter un filtre simple qui évalue l'entrée par rapport à un objet carte:

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

Cela vous permet d'écrire votre balisage comme ceci:

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

21
2017-09-04 14:35



Opérateur ternaire vient d'être ajouté à l'analyseur angulaire dans 1.1.5.

Donc, la façon la plus simple de le faire est maintenant:

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

15
2018-05-23 08:32



C'est ce que j'ai fait récemment:

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

le isShowing valeur est une valeur qui se trouve sur mon contrôleur qui est basculé avec le clic d'un bouton et les parties entre les parenthèses simples sont des classes que j'ai créées dans mon fichier css.

EDIT: Je voudrais également ajouter que codeschool.com a un cours gratuit qui est sponsorisé par google sur AngularJS qui va sur tous ces trucs et puis certains. Il n'y a pas besoin de payer pour quoi que ce soit, inscrivez-vous simplement pour un compte et allez-y! Bonne chance à vous tous!


15
2018-05-27 20:07