Disons que vous avez un tableau rendu dans un ul
avec un li
pour chaque élément et une propriété du contrôleur appelée selectedIndex
. Quelle serait la meilleure façon d’ajouter une classe à li
avec l’index selectedIndex
dans AngularJS?
Je duplique actuellement (à la main) le code li
et l'ajoute à l'une des balises li
et j'utilise ng-show
et ng-hide
pour afficher un seul li
.
Si vous ne souhaitez pas mettre les noms de classe CSS dans Controller comme je le fais, voici un vieux truc que j'utilise depuis les jours précédents. Nous pouvons écrire une expression qui correspond directement à un nom de classe sélectionné, aucune directive personnalisée n'est nécessaire:
ng:class="{true:'selected', false:''}[$index==selectedIndex]"
Veuillez noter l'ancienne syntaxe avec deux points.
Il existe également une nouvelle meilleure façon d'appliquer des classes de manière conditionnelle, comme:
ng-class="{selected: $index==selectedIndex}"
Angular 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 pourrions donc réutiliser des classes CSS existantes en mappant fondamentalement une propriété de modèle à un nom de classe tout en maintenant les classes CSS en dehors du code du contrôleur.
ng-class supporte une expression qui doit être évaluée à
Donc, en utilisant le formulaire 3), nous pouvons simplement écrire
ng-class="{'selected': $index==selectedIndex}"
Voir aussi Comment puis-je appliquer de manière conditionnelle des styles CSS dans AngularJS? pour une réponse plus large.
Mise à jour : Angular 1.1.5 prend en charge un opérateur ternaire , donc si cette construction est plus familier pour vous:
ng-class="($index==selectedIndex) ? 'selected' : ''"
Ma méthode préférée utilise l'expression ternaire.
ng-class="condition ? 'trueClass' : 'falseClass'"
Note: Si vous utilisez une ancienne version de Angular, vous devriez utiliser ceci à la place,
ng-class="condition && 'trueClass' || 'falseClass'"
J'ajouterai à cela car certaines de ces réponses semblent périmées. Voici comment je le fais:
<class="ng-class:isSelected">
Où 'isSelected' est une variable javascript définie dans le contrôleur angular défini.
Pour répondre plus précisément à votre question, voici comment vous pouvez générer une liste avec celle-ci:
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": ""}
]
}
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>
Récemment, j'ai rencontré 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];
};
});
Cela prend un seul argument, qui est soit un tableau à 2 éléments, soit 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>
Si vous voulez aller au-delà de l'évaluation binaire et garder votre CSS en dehors de votre contrôleur, vous pouvez implémenter un simple filtre qui évalue l'entrée par rapport à un objet de la 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>
L'été j'ai récemment fait qui faisait ceci:
<input type="password" placeholder="Enter your password"
ng-class="{true: 'form-control isActive', false: 'isNotActive'}[isShowing]">
La valeur isShowing
est une valeur qui se trouve sur mon contrôleur et que l'on clique en cliquant sur un bouton. Les parties entre les parenthèses simples sont des classes que j'ai créées dans mon fichier css.
EDIT: J'aimerais également ajouter que codeschool.com propose un cours gratuit parrainé par Google sur AngularJS, qui passe en revue tous ces éléments, et plus encore. Il n'y a pas besoin de payer pour quoi que ce soit, il suffit de créer un compte et de commencer! Bonne chance à tous!
Opérateur ternaire vient d'être ajouté à angular analyseur dans 1.1.5 .
Donc, le moyen le plus simple de faire cela est maintenant:
ng:class="($index==selectedIndex)? 'selected' : ''"
Nous pouvons créer une fonction pour gérer la classe de retour avec condition
<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>
Puis
<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>
Vous pouvez vous référer à la page de code complète à l’adresse exemple: ng-class
Ça fonctionne super bien ;)
<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>
Je suis nouveau sur Angular mais j'ai trouvé ceci pour résoudre mon problème:
<i class="icon-download" ng-click="showDetails = ! showDetails" ng-class="{'icon-upload': showDetails}"></i>
Ceci appliquera de manière conditionnelle une classe basée sur un var. Il commence avec icon-download par défaut, using-ng-class, je vérifie l’état de showDetails
si true/false
et applique la classe icon- télécharger. Cela fonctionne très bien.
J'espère que ça aide.
Cela passera probablement pour l'oubli, mais voici comment j'ai utilisé les opérateurs ternaires de la 1.1.5 pour changer de classe selon que la ligne d'une table est la première, la seconde ou la dernière - sauf s'il n'y a qu'une seule ligne dans la table:
<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>
Voici une autre option qui fonctionne bien lorsque ng-class ne peut pas être utilisé (par exemple lors du stylage SVG):
ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"
(Je pense que vous devez être sur la dernière version instable Angular pour utiliser ng-attr-, je suis actuellement sur 1.1.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"
}
};
eh bien, je vous suggère de vérifier la condition de votre contrôleur avec une fonction retournant true ou false.
<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>
et dans votre contrôleur vérifier l'état
$scope.getTodayForHighLight = function(today, date){
return (today == date);
}
C'est dans mon travail multiple juger sous condition:
<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> |
<span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
</li>
J'ajoute simplement quelque chose qui a fonctionné pour moi aujourd'hui, après de nombreuses recherches ...
<div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">
J'espère que cela vous aidera dans votre développement réussi.
=)
Syntaxe d'expression non documentée: Lien excellent vers un site Web ... =)
Si vous avez une classe commune appliquée à de nombreux éléments, vous pouvez créer une directive personnalisée qui l'ajoutera comme ng-show/ng-hide.
Cette directive ajoutera la classe 'active' au bouton si on clique dessus
module.directive('ngActive', ['$animate', function($animate) {
return function(scope, element, attr) {
scope.$watch(attr.ngActive, function ngActiveWatchAction(value){
$animate[value ? 'addClass' : 'removeClass'](element, 'active');
});
};
}]);
Plus d'informations
Si vous utilisez angular avant la v1.1.5 (c’est-à-dire sans opérateur ternaire) et que vous souhaitiez toujours une manière équivalente de définir une valeur dans les deux conditions vous pouvez faire quelque chose comme ceci:
ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"
Vérifier http://www.codinginsight.com/angularjs-if-else-statement/
La tristement célèbre angularjs if else statement !!! Quand j’ai commencé à utiliser Angularjs, j’ai été un peu surpris de ne pas trouver d’instruction if/else.
Donc, je travaillais sur un projet et j'ai remarqué que lors de l'utilisation de l'instruction if/else, la condition apparaît lors du chargement. Vous pouvez utiliser ng-cloak pour résoudre ce problème.
<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 }
Merci amadou
Vous pouvez utiliser le package this npm. Il gère tout et propose des options pour les classes statiques et conditionnelles basées sur une variable ou une fonction.
// 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})} />