Apa cara terbaik untuk menerapkan suatu kelas secara kondisional?

1183

Katakanlah Anda memiliki array yang diberikan dalam uldengan liuntuk setiap elemen dan properti pada controller yang disebut selectedIndex. Apa yang akan menjadi cara terbaik untuk menambahkan kelas lidengan indeks selectedIndexdi AngularJS?

Saat ini saya sedang menduplikasi (dengan tangan) likode dan menambahkan kelas ke salah satu litag dan menggunakan ng-showdan ng-hidehanya menampilkan satu liper indeks.

hormatilah Kode
sumber
2
Jawaban untuk pertanyaan ini menunjukkan bahwa ada lebih banyak templat daripada {{varname}}. Di mana saya dapat menemukan dokumentasi tentang apa lagi yang ada untuk templating, seperti operator ternary dalam beberapa bentuk yang berbeda? docs.angularjs.org/guide/templates tampaknya tidak menjelaskan apa yang ditawarkan templating dalam hal persyaratan dll. selain {{varname.fieldname}}.
Christos Hayward
ini sangat berguna bagi saya harap ini akan bekerja untuk Anda tech-blog.maddyzone.com/javascript/…
Rituraj ratan

Jawaban:

1384

Jika Anda tidak ingin memasukkan nama kelas CSS ke Controller seperti yang saya lakukan, ini adalah trik lama yang saya gunakan sejak pra-v1 hari. Kami dapat menulis ekspresi yang mengevaluasi langsung ke nama kelas yang dipilih , tidak ada arahan khusus yang diperlukan:

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

Harap perhatikan sintaks lama dengan titik dua.

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

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

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

Namun cara-cara ini secara fungsional tidak sama. Berikut ini sebuah contoh:

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

Karena itu kami dapat menggunakan kembali kelas CSS yang ada dengan memetakan properti model pada nama kelas dan pada saat yang sama menjauhkan kelas CSS dari kode Pengontrol.

orcun
sumber
33
OP, itu mungkin cara terburuk untuk mengekspresikan operator ternary yang pernah saya lihat. Sudahkah Anda mempertimbangkan ($index==selectedIndex) ? 'selected' : ''?
Malvolio
17
@Malvolio AFAIR, operator ternary tidak berfungsi dalam ekspresi sudut di v0.9.x. Ini lebih atau kurang sebuah saklar.
orcun
36
ng-class (per 1/19/2012) sekarang mendukung ekspresi yang harus mengevaluasi 1) string nama kelas yang dibatasi ruang, atau 2) dan array nama kelas, atau 3) peta / objek kelas nama ke nilai boolean. Jadi, menggunakan 3): ng-class = "{terpilih: $ index == selectedIndex}"
Mark Rajcok
2
Terima kasih @ark, BTW sekarang saya telah memeriksa saya dapat mengatakan bahwa metode ini berfungsi di v1. Itu masih berguna dalam beberapa kasus. Perhatikan bahwa nama properti objek (kunci) tidak selalu benar atau salah, itu bisa berupa apa saja yang Anda ingin petakan ke nama kelas.
orcun
6
Saya hanya ingin menambahkan, saya mengalami masalah karena saya menggunakan sintaksis suka {classname: '$index === selectedIndex'} dan tidak berfungsi. Ketika saya menyatukan semuanya dan menggunakan == alih-alih === itu berhasil. {classname: '$index==selectedIndex'}
Lucas
437

ng-class mendukung ekspresi yang harus dievaluasi

  1. String nama kelas yang dibatasi ruang, atau
  2. Array nama kelas, atau
  3. Peta / objek nama kelas ke nilai boolean.

Jadi, menggunakan form 3) kita cukup menulis

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

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


Pembaruan : Angular 1.1.5 telah menambahkan dukungan untuk operator ternary , jadi jika konstruk itu lebih familier bagi Anda:

ng-class="($index==selectedIndex) ? 'selected' : ''"
Mark Rajcok
sumber
2
+1 untuk operator ternary (dan saya butuh satu sekarang) tetapi 1.1. * Adalah 'rilis tidak stabil' di mana API dapat berubah tanpa pemberitahuan - pada saat pengetikan. 1.0. * Stabil, jadi saya akan lebih nyaman dengan itu untuk proyek yang akan diluncurkan minggu depan selama 6 bulan.
Dave Everitt
1
ng-class="{'selected': $index==selectedIndex}"bekerja untuk saya
knuhol
160

Metode favorit saya adalah menggunakan ekspresi ternary.

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'"
skmvasu
sumber
2
Ini membantu saya menulis ungkapan ini: ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}". Tidak dapat menemukan cara lain.
dduft
Saya benar-benar tidak menemukan mengapa modalFlag boolean scoped saya tidak memperbarui - ng-class = "{'closed': modalFlag, 'open':! ModalFlag}" Saya mencoba untuk menambah baik tertutup atau terbuka tergantung pada variabel scoped / boolean - Jika ada yang bisa membantu saya akan sangat berterima kasih -Terima kasih.
mendarat
Ini diperkenalkan sebagai versi 1.5. github.com/angular/angular.js/commit/…
Mubashir Koul
55

Saya akan menambahkan ini, karena beberapa jawaban ini sepertinya sudah ketinggalan zaman. Begini cara saya melakukannya:

<class="ng-class:isSelected">

Di mana 'isSelected' adalah variabel javascript yang didefinisikan dalam pengontrol bersudut scoped.


Untuk lebih spesifik menjawab pertanyaan Anda, inilah cara Anda dapat membuat 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

stefano
sumber
Apa perbedaan antara class = "ng-class: item.isSelected" dan ng-class = "item.isSelected"
zloctb
Ingin tahu tentang penggunaan ng-class:classNamevs hanya menggunakan class="{{className}}"?
Roi
48

Berikut ini adalah solusi yang 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>


sumber
74
Saya sangat merekomendasikan untuk menjaga controller Anda dari hal-hal CSS. Itu jalan yang tidak ingin kau lewati.
leviathan
1
Nama kelas termasuk dalam templat
Casey
5
Pada titik tertentu, jsfiddle mungkin ketinggalan membayar tagihan mereka, atau memilih untuk pindah ke domain lain, atau orang yang bertanggung jawab terbunuh oleh bus (lihat juga Bus Factor). Jadi bisakah saya meminta Anda untuk menjelaskan apa yang dilakukan biola itu, dalam jawaban Anda? Ini juga kanonik pada stack overflow.
Sebastian Mach
27

Saya menghadapi masalah yang sama baru-baru ini dan memutuskan untuk hanya 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 argumen tunggal, yang merupakan array 2-elemen atau string, yang akan berubah 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>
Lèse majesté
sumber
1
saya untuk saya baru saja dibuat untuk contoh yesNo () filter mengembalikan kelas 'ya' atau 'tidak' menurut nilai boolean 1 o 0:filter('yesNo', function() { return function(input) { // info('yesNo('+ input +')'); switch(input){ case '1': return ' yes '; break; default: return ' no '; break; } } });
svassr
1
ng-class dapat menangani peta / objek dari nama kelas hingga nilai boolean, jadi Anda bisa menulis yang berikut: ng-class = "{yes: some_boolean_expression, no: some_other_boolean_expression}" Eg, ng-class = "{yes: input , no
:!
21

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

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

Ini memungkinkan Anda untuk menulis markup Anda seperti ini:

<div ng-class="muppets.star|switch:{'Kermit':'green', 'Miss Piggy': 'pink', 'Animal': 'loud'}">
    ...
</div>
Joe Steele
sumber
Hai @ Jo, ada ide bagaimana menangani nilai nol? Jika saya memasukkan nol dalam input, itu tidak akan memetakan kelasnya ...
dalcam
1
@ user1191559 - Anda dapat item 'default' ke peta, lalu mengembalikan nilai itu jika 'input' adalah nol.
Joe Steele
17

Saya baru-baru ini melakukan yang melakukan ini:

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

The isShowingnilai adalah nilai yang terletak di controller saya yang akan toggle dengan klik tombol dan bagian-bagian antara kurung tunggal kelas saya buat dalam file css saya.

EDIT: Saya juga ingin menambahkan bahwa codeschool.com memiliki kursus gratis yang disponsori oleh google di AngularJS yang membahas semua hal ini dan kemudian beberapa. Tidak perlu membayar apa pun, cukup daftar untuk akun dan mulai! Semoga sukses untuk Anda semua!

Pytth
sumber
Bisakah Anda memberikan biola atau lebih banyak kode di sini? Apakah isShowingarray di controller itu?
Kyle Pennell
Saya kira boolean
Mirko
15

Operator ternary baru saja ditambahkan ke parser sudut di 1.1.5 .

Jadi cara paling sederhana untuk melakukan ini adalah sekarang:

ng:class="($index==selectedIndex)? 'selected' : ''"
singa hutan
sumber
Juga: class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';".
peter
11

Kita dapat membuat fungsi untuk mengelola kelas kembali dengan kondisi

masukkan deskripsi gambar di sini

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

Lalu

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

Anda dapat merujuk ke halaman kode lengkap di kelas ng misalnya

Lewis Hai
sumber
9

Saya baru mengenal Angular tetapi telah menemukan ini untuk menyelesaikan masalah saya:

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

Ini akan secara kondisional menerapkan kelas berdasarkan var. Dimulai dengan ikon-unduhan sebagai default, menggunakan kelas-ng, saya memeriksa status showDetailsjika true/falsedan menerapkan kelas -ikon unggah . Ini bekerja dengan baik.

Semoga ini bisa membantu.

Ravi Ram
sumber
9

Ini berfungsi seperti pesona;)

<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>
Aliti
sumber
5

Ini mungkin akan diturunkan untuk dilupakan, tetapi di sini adalah bagaimana saya menggunakan operator ternary 1.1.5 untuk beralih kelas tergantung pada apakah baris dalam tabel adalah yang pertama, tengah atau terakhir - kecuali jika hanya ada satu baris dalam tabel:

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

Ini dalam pekerjaan saya, beberapa hakim kondisional:

<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>
H. jame
sumber
4

Berikut adalah opsi lain yang berfungsi dengan baik ketika ng-class tidak dapat digunakan (misalnya saat menata SVG):

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

(Saya pikir Anda harus menggunakan Angular terbaru yang tidak stabil untuk menggunakan ng-attr-, saya saat ini di 1.1.4)

Ashley Davis
sumber
4

baik saya akan menyarankan Anda untuk memeriksa kondisi di controller Anda dengan fungsi yang mengembalikan benar atau salah .

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

dan di controller Anda periksa kondisinya

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

sebagian

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

pengontrol

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

Jika Anda menggunakan sudut pra v1.1.5 (yaitu tidak ada operator ternary) dan Anda masih menginginkan cara yang setara untuk menetapkan nilai di kedua kondisi Anda dapat melakukan sesuatu seperti ini:

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

Jika Anda memiliki kelas umum yang diterapkan ke banyak elemen, Anda dapat membuat arahan khusus yang akan menambahkan kelas itu seperti ng-show / ng-hide.

Arahan ini akan menambahkan kelas 'aktif' ke tombol jika diklik

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

Info lebih lanjut

lars1595
sumber
3

Hanya menambahkan sesuatu yang bekerja untuk saya hari ini, setelah banyak mencari ...

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

Semoga ini membantu dalam pengembangan sukses Anda.

=)

Sintaks Ekspresi Tidak Berdokumen: Tautan Situs Web Hebat ... =)

Robert Green MBA
sumber
Lihatlah jawaban yang diterima. Itu melakukan hal yang sama dan memberikan lebih banyak contoh.
respectTheCode
3

Lihat ini .

if|elsePernyataan AngularJS yang terkenal !!!
Ketika saya mulai menggunakan Angularjs, saya agak terkejut bahwa saya tidak dapat menemukan pernyataan if / else.

Jadi saya sedang mengerjakan sebuah proyek dan saya perhatikan bahwa ketika menggunakan pernyataan if / else, kondisi tersebut menunjukkan saat memuat. Anda dapat menggunakan ng-jubah untuk memperbaikinya.

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

Terima kasih amadou

Victor Cruz
sumber
0

Kamu bisa menggunakan paket npm ini . Ini menangani semuanya dan memiliki opsi untuk kelas statis dan bersyarat berdasarkan pada variabel atau fungsi.

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