Pertanyaan Apa cara terbaik untuk menerapkan kelas secara kondisional?


Katakanlah Anda memiliki larik yang diberikan dalam ul dengan sebuah li untuk setiap elemen dan properti pada kontroler yang dipanggil selectedIndex. Apa yang akan menjadi cara terbaik untuk menambahkan kelas ke li dengan indeks selectedIndex di AngularJS?

Saat ini saya menduplikasi (dengan tangan) li kode dan menambahkan kelas ke salah satu li tag dan menggunakan ng-show dan ng-hide untuk hanya menampilkan satu li per indeks.


1132
2017-10-17 10:49


asal


Jawaban:


Jika Anda tidak ingin menempatkan nama-nama kelas CSS ke dalam Controller seperti yang saya lakukan, di sini adalah trik lama yang saya gunakan sejak pra-v1 hari. Kita dapat menulis ekspresi yang mengevaluasi langsung ke nama kelas terpilih, tidak ada arahan khusus yang diperlukan:

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

Harap perhatikan sintaks lama dengan tanda titik dua. 

Ada juga cara baru yang lebih baik untuk menerapkan kelas secara kondisional, seperti:

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

Sudut sekarang mendukung ekspresi yang mengembalikan objek. Setiap properti (nama) dari objek ini sekarang dianggap sebagai nama kelas dan diterapkan tergantung pada nilainya.

Namun cara-cara ini tidak secara fungsional sama. Berikut ini contohnya:

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

Oleh karena itu, kami dapat menggunakan kembali kelas CSS yang ada dengan memetakan properti model ke nama kelas dan pada saat yang sama menjaga kelas CSS dari kode Pengontrol.


1367
2017-11-29 11:17



ng-kelas mendukung ekspresi yang harus dievaluasi baik

  1. String nama kelas yang dipisahkan dengan spasi, atau
  2. Array nama kelas, atau
  3. Peta / objek nama kelas ke nilai boolean.

Jadi, dengan menggunakan formulir 3) kita bisa menulis

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

Lihat juga Bagaimana cara menerapkan gaya CSS secara kondisional di AngularJS? untuk jawaban yang lebih luas.


Memperbarui: Angular 1.1.5 menambahkan dukungan untuk a operator terner, jadi jika konstruksinya lebih akrab bagi Anda:

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

432
2017-08-28 01:13



Metode favorit saya adalah menggunakan ekspresi terner.

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

catatan: Jika Anda menggunakan versi Angular yang lebih lama, Anda harus menggunakan ini sebagai gantinya,

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

155
2017-09-27 13:39



Saya akan menambahkan ini, karena beberapa jawaban ini kedaluwarsa. Inilah cara saya melakukannya:

<class="ng-class:isSelected">

Where 'isSelected' adalah variabel javascript yang ditentukan di dalam pengontrol sudut bersudut.


Untuk lebih spesifik menjawab pertanyaan Anda, berikut ini cara Anda menghasilkan daftar dengan itu:

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


Lihat: http://jsfiddle.net/tTfWM/

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


53
2017-09-27 02:01



Berikut ini adalah solusi yang jauh lebih sederhana:

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



Saya menghadapi masalah serupa baru-baru ini dan memutuskan untuk membuat filter bersyarat:

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

Dibutuhkan satu argumen, yang merupakan array 2-elemen atau string, yang akan diubah menjadi array yang ditambahkan string kosong sebagai elemen kedua:

<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



Jika Anda ingin melampaui evaluasi biner dan menjaga CSS Anda keluar dari pengontrol, Anda dapat menerapkan filter sederhana yang mengevaluasi masukan terhadap objek peta:

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

Ini memungkinkan Anda untuk menulis markup seperti ini:

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

21
2017-09-04 14:35



Operator Ternary baru saja ditambahkan ke parser angular di 1.1.5.

Jadi cara paling sederhana untuk melakukan ini adalah sekarang:

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

15
2018-05-23 08:32