it-swarm.com.de

Was ist der beste Weg, um eine Klasse bedingt anzuwenden?

Nehmen wir an, Sie haben ein Array, das in einem ul mit einem li für jedes Element und einer Eigenschaft auf dem Controller namens selectedIndex gerendert wird. Was wäre der beste Weg, um eine Klasse zum li mit dem Index selectedIndex in AngularJS hinzuzufügen?

Momentan dupliziere ich (von Hand) den li-Code und füge die Klasse zu einem der li-Tags hinzu und verwende ng-show und ng-hide, um nur einen li pro Index anzuzeigen.

1166
respectTheCode

Wenn Sie CSS-Klassennamen nicht wie ich in Controller einfügen möchten, ist hier ein alter Trick, den ich seit Tagen vor Version 1 verwende. Wir können einen Ausdruck schreiben, der direkt zu einem Klassennamen ausgewertet wird ausgewählt, es sind keine benutzerdefinierten Anweisungen erforderlich:

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

Bitte beachten Sie die alte Syntax mit Doppelpunkt.

Es gibt auch eine neue, bessere Möglichkeit, Klassen bedingt anzuwenden, wie zum Beispiel:

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

Angular unterstützt jetzt Ausdrücke, die ein Objekt zurückgeben. Jede Eigenschaft (Name) dieses Objekts wird jetzt als Klassenname betrachtet und abhängig von seinem Wert angewendet.

Diese Wege sind jedoch funktionell nicht gleich. Hier ist ein Beispiel:

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

Wir könnten daher vorhandene CSS-Klassen wiederverwenden, indem wir im Grunde eine Modelleigenschaft einem Klassennamen zuordnen und gleichzeitig CSS-Klassen aus dem Controller-Code heraushalten.

1378
orcun

ng-class unterstützt einen Ausdruck, der zu einem von beiden ausgewertet werden muss

  1. Eine Zeichenfolge von durch Leerzeichen getrennten Klassennamen oder
  2. Ein Array von Klassennamen oder
  3. Eine Zuordnung/ein Objekt von Klassennamen zu booleschen Werten.

Mit Formular 3) können wir also einfach schreiben

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

Siehe auch Wie wende ich CSS-Stile in AngularJS bedingt an? für eine umfassendere Antwort.


Update : Angular 1.1.5 unterstützt jetzt einen ternären Operator Ihnen vertrauter:

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

Meine Lieblingsmethode ist die Verwendung des ternären Ausdrucks.

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

Hinweis: Wenn Sie eine ältere Version von Angular verwenden, sollten Sie stattdessen diese verwenden.

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

Ich werde noch etwas hinzufügen, da einige dieser Antworten veraltet zu sein scheinen. So mache ich es:

<class="ng-class:isSelected">

Wobei 'isSelected' eine Javascript-Variable ist, die im Bereich angular Controller definiert ist.


Um Ihre Frage genauer zu beantworten, können Sie hiermit eine Liste erstellen:

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


Siehe: http://jsfiddle.net/tTfWM/

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

54
stefano

Hier ist eine viel einfachere Lösung:

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
user81962

Vor kurzem hatte ich ein ähnliches Problem und habe beschlossen, nur einen bedingten Filter zu erstellen:

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

Es wird ein einzelnes Argument benötigt, entweder ein Array mit zwei Elementen oder eine Zeichenfolge, die in ein Array umgewandelt wird, an das eine leere Zeichenfolge als zweites Element angehängt wird:

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

Wenn Sie über die binäre Auswertung hinausgehen und Ihr CSS von Ihrem Controller fernhalten möchten, können Sie einen einfachen Filter implementieren, der die Eingabe anhand eines Kartenobjekts bewertet:

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

Auf diese Weise können Sie Ihr Markup folgendermaßen schreiben:

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

Das, was ich kürzlich getan habe, war folgendes:

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

Der isShowing -Wert ist ein Wert, der sich auf meinem Controller befindet und mit einem Klick auf eine Schaltfläche umgeschaltet wird. Die Teile zwischen den einzelnen Klammern sind Klassen, die ich in meiner CSS-Datei erstellt habe.

EDIT: Ich möchte auch hinzufügen, dass codeschool.com einen kostenlosen Kurs hat, der von Google auf AngularJS gesponsert wird und all diese Dinge und noch einige mehr behandelt. Sie müssen nichts bezahlen, nur ein Konto eröffnen und loslegen! Viel Glück euch allen!

17
Pytth

Ternärer Operator wurde gerade hinzugefügt zu angular Parser in 1.1.5 .

Der einfachste Weg dies zu tun ist jetzt:

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

Wir können eine Funktion erstellen, um die Rückgabeklasse mit Bedingung zu verwalten

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>

Und dann

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

Sie können auf die vollständige Codepage unter ng-class wenn Beispiel verweisen

11
Lewis Hai

Das funktioniert wie ein Zauber;)

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

Ich bin neu in Angular, habe jedoch Folgendes gefunden, um mein Problem zu lösen:

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

Dies wird eine Klasse, die auf einer var basiert, bedingt anwenden. Es beginnt mit einem icon-download als Voreinstellung, der using ng-class, ich überprüfe den Status von showDetails if true/false und wende class icon- upload. Es funktioniert großartig.

Ich hoffe es hilft.

9
Ravi Ram

Dies wird wahrscheinlich in Vergessenheit geraten, aber so habe ich die ternären Operatoren von 1.1.5 verwendet, um Klassen zu wechseln, je nachdem, ob eine Zeile in einer Tabelle die erste, die mittlere oder die letzte ist - es sei denn, die Tabelle enthält nur eine Zeile:

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

Hier ist eine weitere Option, die gut funktioniert, wenn ng-class nicht verwendet werden kann (zum Beispiel beim Stylen von SVG):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

(Ich denke, Sie müssen auf dem neuesten instabilen Angular sein, um ng-attr- zu verwenden, ich bin derzeit auf 1.1.4.)

4
Ashley Davis

teilweise

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

regler

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

nun, ich würde Ihnen vorschlagen, den Zustand in Ihrem Controller mit einer Funktion zu überprüfen, die true oder false zurückgibt.

<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>

und in Ihrem Controller überprüfen Sie den Zustand

$scope.getTodayForHighLight = function(today, date){
return (today == date);
}
4
sheelpriy

Dies ist in meiner Arbeit mehrfach bedingt zu beurteilen:

<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> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
  <span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
</li>
4
H.jame

Ich füge nur etwas hinzu, das heute nach langem Suchen für mich funktioniert hat ...

<div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">

Ich hoffe, dies hilft Ihnen bei Ihrer erfolgreichen Entwicklung.

=)

Syntax für nicht dokumentierte Ausdrücke: Hervorragender Website-Link ... =)

3

Wenn Sie eine gemeinsame Klasse haben, die auf viele Elemente angewendet wird, können Sie eine benutzerdefinierte Direktive erstellen, die diese Klasse wie ng-show/ng-hide hinzufügt.

Diese Direktive fügt der Schaltfläche die Klasse 'active' hinzu, wenn darauf geklickt wird

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

Mehr Info

3
lars1595

Wenn Sie angular vor v1.1.5 (dh keinen ternären Operator) verwenden und weiterhin möchten eine äquivalente Möglichkeit, einen Wert in beide zu setzen, können Sie folgendermaßen vorgehen:

ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"
3
Scotty.NET

Überprüfen Sie http://www.codinginsight.com/angularjs-if-else-statement/

Die berüchtigten anglejs wenn sonst Aussage !!! Als ich anfing, Angularjs zu verwenden, war ich etwas überrascht, dass ich keine if/else-Anweisung finden konnte.

Ich habe an einem Projekt gearbeitet und festgestellt, dass beim Verwenden der if/else-Anweisung die Bedingung beim Laden angezeigt wird. Sie können ng-cloak verwenden, um dies zu beheben.

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

Vielen Dank amadou

3
Victor Cruz

Sie können das Paket this npm verwenden. Es behandelt alles und bietet Optionen für statische und bedingte Klassen, die auf einer Variablen oder einer Funktion basieren.

// 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})} />
0
Tushar Sharma