css - proprietà - Qual è il modo migliore per applicare in modo condizionale una classe?




css più classi (15)

Diciamo che hai un array che è reso in un ul con un li per ogni elemento e una proprietà sul controller chiamata selectedIndex . Quale sarebbe il modo migliore per aggiungere una classe al li con l'indice selectedIndex in AngularJS?

Attualmente sto duplicando (a mano) il codice li e aggiungendo la classe a uno dei tag li e usando ng-show e ng-hide per mostrare solo un li per indice.

https://code.i-harness.com


parziale

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

controllore

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

Aggiungerò a questo, perché alcune di queste risposte sembrano obsolete. Ecco come lo faccio:

<class="ng-class:isSelected">

Dove 'isSelected' è una variabile javascript definita all'interno del controller angolare.


Per rispondere in modo più specifico alla tua domanda, ecco come potresti generare un elenco con questo:

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


Vedi: http://jsfiddle.net/tTfWM/

Vedi: ng-class


Controlla http://www.codinginsight.com/angularjs-if-else-statement/

Il famigerato angularjs se altro affermazione !!! Quando ho iniziato ad usare Angularjs, ero un po 'sorpreso di non riuscire a trovare un'istruzione if / else.

Quindi stavo lavorando a un progetto e ho notato che quando si utilizzava l'istruzione if / else, la condizione veniva visualizzata durante il caricamento. Puoi usare ng-cloak per risolvere questo problema.

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

Grazie amadou


Di recente ho affrontato un problema simile e ho deciso di creare un filtro condizionale:

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

Prende un singolo argomento, che è o un array di 2 elementi o una stringa, che viene trasformato in un array che viene aggiunto ad una stringa vuota come secondo elemento:

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

Ecco una soluzione molto più semplice:

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>


Funziona correttamente;)

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

L'ho fatto di recente che stava facendo questo:

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

Il valore isShowing è un valore che si trova sul mio controller che viene attivato con il clic di un pulsante e le parti tra le singole parentesi sono le classi che ho creato nel mio file css.

EDIT: Vorrei anche aggiungere che codeschool.com ha un corso gratuito sponsorizzato da google su AngularJS che ripercorre tutte queste cose e poi alcune. Non è necessario pagare nulla, basta registrarsi per un account e iniziare! Buona fortuna a tutti voi!


L'operatore ternario è stato appena aggiunto al parser angolare in 1.1.5 .

Quindi il modo più semplice per farlo è ora:

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

Probabilmente questo verrà downvoted all'oblio, ma ecco come ho usato gli operatori ternari di 1.1.5 per cambiare classe a seconda che una riga in una tabella sia la prima, la metà o l'ultima - eccetto se c'è una sola riga nella tabella:

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

Puoi usare this pacchetto npm. Gestisce tutto e ha opzioni per classi statiche e condizionali basate su una variabile o una funzione.

// 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})} />

Se hai una classe comune che viene applicata a molti elementi, puoi creare una direttiva personalizzata che aggiungerà quella classe come ng-show / ng-hide.

Questa direttiva aggiungerà la classe 'attiva' al pulsante se viene cliccata

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

Ulteriori informazioni


Se non vuoi mettere i nomi delle classi CSS in Controller come faccio io, ecco un vecchio trucco che uso fin dai tempi pre-v1. Possiamo scrivere un'espressione che valuta direttamente il nome di una classe selezionata , non sono necessarie direttive personalizzate:

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

Si prega di notare la vecchia sintassi con due punti.

C'è anche un nuovo modo migliore di applicare le classi in modo condizionale, come:

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

Angular ora supporta espressioni che restituiscono un oggetto. Ogni proprietà (nome) di questo oggetto è ora considerata come un nome di classe e viene applicata in base al suo valore.

Tuttavia questi modi non sono funzionalmente uguali. Ecco un esempio:

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

Potremmo quindi riutilizzare le classi CSS esistenti, essenzialmente mappando una proprietà del modello a un nome di classe e allo stesso tempo mantenendo le classi CSS fuori dal codice del controller.


Se vuoi andare oltre la valutazione binaria e tenere il tuo CSS fuori dal tuo controller, puoi implementare un semplice filtro che valuta l'input rispetto a un oggetto della mappa:

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

Questo ti permette di scrivere il tuo markup in questo modo:

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

Sono nuovo di Angular ma ho trovato questo per risolvere il mio problema:

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

Ciò applicherà condizionalmente una classe basata su una var. Inizia con un download di icone di default, usando la classe ng, controllo lo stato di showDetails se true/false e applico l' icona di classe -upload . Funziona alla grande.

Spero che sia d'aiuto.


ng-class supporta un'espressione che deve valutare entrambi

  1. Una stringa di nomi di classi delimitati da spazio, o
  2. Una serie di nomi di classi, o
  3. Una mappa / oggetto di nomi di classi in valori booleani.

Quindi, usando il modulo 3) possiamo semplicemente scrivere

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

Vedi anche Come faccio a applicare in modo condizionale stili CSS in AngularJS? per una risposta più ampia

Aggiornamento : Angular 1.1.5 ha aggiunto il supporto per un operatore ternario , quindi se quel costrutto ti è più familiare:

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




angularjs