Bir sınıfı şartlı olarak uygulamanın en iyi yolu nedir?


1183

Diyelim ki, her öğe için bir ulile live bir denetleyicide çağrılan bir özellik ile işlenmiş bir dizi var selectedIndex. AngularJS lidizinine ile bir sınıf eklemenin en iyi yolu nedir selectedIndex?

Şu anda (el ile) likodu çoğaltmak ve sınıf birine liEtiketler ekleme ve kullanarak ng-showve her dizin için ng-hideyalnızca birini göstermek için li.


2
Bu sorunun cevapları, şablonda {{varname}} 'den daha fazla şey olduğunu göstermektedir. Üçlü formdaki üçlü operatör gibi şablonlama için daha neler olduğuna dair belgeleri nerede bulabilirim? docs.angularjs.org/guide/templates , {{varname.fieldname}} dışında koşulların vb.
Christos Hayward

Bu benim için çok yararlı olur umarım sizin için çalışacaktır tech-blog.maddyzone.com/javascript/…
Rituraj ratan

Yanıtlar:


1384

Benim gibi CSS sınıf isimlerini Controller'a koymak istemiyorsanız, v1 öncesi günlerden beri kullandığım eski bir numara. Seçilen sınıf adına doğrudan değerlendiren bir ifade yazabiliriz , özel direktif gerekmez:

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

Lütfen iki nokta üst üste sözdizimini not edin.

Sınıfları şartlı olarak uygulamanın yeni ve daha iyi bir yolu da vardır:

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

Açısal artık bir nesneyi döndüren ifadeleri desteklemektedir. Bu nesnenin her özelliği (adı) artık bir sınıf adı olarak kabul edilir ve değerine bağlı olarak uygulanır.

Ancak bu yollar işlevsel olarak eşit değildir. İşte bir örnek:

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

Bu nedenle, temel olarak bir model özelliğini bir sınıf adıyla eşleştirerek ve aynı zamanda CSS sınıflarını Denetleyici kodunun dışında tutarak mevcut CSS sınıflarını yeniden kullanabiliriz.


33
OP, bu gördüğüm üçlü operatörü ifade etmenin en kötü yolu olabilir. Düşündün mü ($index==selectedIndex) ? 'selected' : ''?
Malvolio

17
@Malvolio AFAIR, üçlü operatör v0.9.x'de açısal ifadeler içinde çalışmıyordu. Bu aşağı yukarı bir anahtar.
orcun

36
ng-class (1/19/2012 itibariyle) artık 1) boşlukla sınırlandırılmış sınıf isimleri dizisi veya 2) ve sınıf isimleri dizisi ya da 3) sınıf haritası / nesnesi isimleri boole değerlerine dönüştürür. Yani, 3 kullanarak): ng-class = "{selected: $ index == selectedIndex}"
Mark Rajcok

2
Teşekkürler @ Mark, BTW şimdi kontrol ettim, bu yöntemin v1'de çalıştığını söyleyebilirim. Bazı durumlarda hala yararlıdır. Nesne özellik adlarının (anahtarlar) mutlaka doğru veya yanlış olmadığını, bir sınıf adıyla eşlemek isteyebileceğiniz herhangi bir şey olabileceğini unutmayın.
orcun

6
Sadece eklemek istiyorum, sözdizimi kullandığım için bir sorun yaşıyordum {classname: '$index === selectedIndex'} ve işe yaramadı. Her şeyi bir araya getirip === yerine == kullandığımda işe yaradı. {classname: '$index==selectedIndex'}
Lucas

437

ng-class aşağıdakilerden birini değerlendirmesi gereken bir ifadeyi destekler:

  1. Boşlukla sınırlandırılmış sınıf adları dizesi veya
  2. Bir sınıf adı dizisi veya
  3. Sınıf adlarının boole değerleriyle eşlemesi / nesnesi.

Böylece, form 3'ü kullanarak)

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

Ayrıca bkz . AngularJS'de CSS stillerini koşullu olarak nasıl uygularım? daha geniş bir cevap için.


Güncelleme : Açısal 1.1.5, üçlü bir operatör için destek eklediğinden , bu yapı size daha tanıdık geliyorsa:

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

2
Üçlü operatörler için +1 (ve şu anda bir tanesine ihtiyacım var) ama 1.1. *, API'nın önceden haber verilmeksizin değişime tabi olduğu bir 'kararsız sürümdür.' 1.0. * Stabildir, bu yüzden bir projenin önümüzdeki hafta 6 ay boyunca piyasaya sürülmesinden daha rahat olurdum.
Dave Everitt

1
ng-class="{'selected': $index==selectedIndex}"benim için çalışıyor
knuhol

160

En sevdiğim yöntem üçlü ifadeyi kullanmak.

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

Not: Angular'ın daha eski bir sürümünü kullanıyorsanız, bunun yerine bunu kullanmalısınız,

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

2
Bu, bu ifadeyi yazma bana yardımcı oldu: ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}". Başka bir yol bulamadı.
dduft

Gerçekten benim kapsamlandırılmış boolean modalFlag neden güncellemiyor bulmuyorum - ng-class = "{'kapalı': modalFlag, 'open':! ModalFlag}" Kapsamlı değişken / boolean'a bağlı olarak kapalı veya açık eklemeye çalışıyorum - eğer biri yardım edebilirse çok minnettar olurum. teşekkür ederim.
indi

Bu 1.5 sürümü olarak tanıtıldı. github.com/angular/angular.js/commit/…
Mubashir Koul

55

Buna ekleyeceğim, çünkü bu cevapların bazıları güncel değil. İşte nasıl yaparım:

<class="ng-class:isSelected">

Burada 'isSelected', kapsamlandırılmış açısal denetleyicide tanımlanan bir javascript değişkenidir.


Sorunuzu daha ayrıntılı olarak ele almak için, bununla nasıl bir liste oluşturabileceğiniz aşağıda açıklanmıştır:

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


Bkz. Http://jsfiddle.net/tTfWM/

Bkz. Http://docs.angularjs.org/api/ng.directive:ng


Class = "ng-class: item.isSelected" ve ng-class = "item.isSelected" arasındaki
farklar

ng-class:classNameSadece kullanmak vs vs merak mı ediyorsunuz class="{{className}}"?
Roi

48

İşte çok daha basit bir çözüm:

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>


74
Denetleyicinizi CSS öğelerinden uzak tutmanızı önemle tavsiye ederim. Bu, gitmek istemediğiniz bir yol.
leviathan

1
Sınıf isimleri şablona aittir
Casey

5
Bir noktada, jsfiddle faturalarını ödemeyi veya başka bir alana taşınmayı seçebilir veya sorumlu insanlar bir otobüs tarafından öldürülür (ayrıca bkz. Otobüs Faktörü). Cevabınız içinde bu kemanın ne yaptığını açıklamanızı isteyebilir miyim ? Bu, yığın taşması üzerinde de kanoniktir.
Sebastian Mach

27

Son zamanlarda benzer bir sorunla karşılaştım ve sadece koşullu bir filtre oluşturmaya karar verdim:

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

İkinci eleman olarak boş bir dize eklenmiş bir diziye dönüştürülen 2 öğeli bir dizi veya dize olan tek bir bağımsız değişken alır:

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

1
Ben sadece ben sadece bir evetNo () filtre boolean değeri 1 o 0 göre sınıfları 'yes' veya 'no' döndüren örnek için yarattı:filter('yesNo', function() { return function(input) { // info('yesNo('+ input +')'); switch(input){ case '1': return ' yes '; break; default: return ' no '; break; } } });
svassr

1
ng-sınıfı, boole değerlerine sınıf adlarının bir haritasını / nesnesini işleyebilir, böylece aşağıdakileri yazmanız yeterlidir: ng-class = "{yes: some_boolean_expression, no: some_other_boolean_expression}" Ör. ng-class = "{yes: input , no
:!

21

İkili değerlendirmenin ötesine geçmek ve CSS'nizi denetleyicinizden uzak tutmak istiyorsanız, girdiyi bir harita nesnesine göre değerlendiren basit bir filtre uygulayabilirsiniz:

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

Bu, işaretlemenizi şöyle yazmanıza olanak tanır:

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

Merhaba @Joe, nasıl null değerleri işlemek için herhangi bir fikir? Ben girişte null geçmek, onun sınıf harita alışkanlık ...
dalcam

1
@ user1191559 - haritaya 'varsayılan' bir öğe ekleyebilir, ardından 'giriş' boşsa bu değeri döndürebilirsiniz.
Joe Steele

17

Son zamanlarda bunu yapıyordu yaptım:

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

isShowingDeğeri benim css dosyasındaki bir düğmeye tek parantez arasındaki parçaların tıklama ile konum değiştirir alır benim denetleyicisinde yarattığım sınıfları vardır bulunan bir değerdir.

EDIT: Ayrıca codeschool.com tüm bu şeyler ve daha sonra bazı gider AngularJS google tarafından desteklenen ücretsiz bir kursu olduğunu eklemek istiyorum. Hiçbir şey için ödeme yapmanıza gerek yok, sadece bir hesap için kayıt olun ve başlayın! Hepinize iyi şanslar!


Burada bir kod veya daha fazla kod verebilir misiniz? isShowingDenetleyicide bir dizi var mı ?
Kyle Pennell

Sanırım bir boolean
Mirko

15

Üçlü operatör sadece edilmiş açısal ayrıştırıcı ilave 1.1.5 .

Yani bunu yapmanın en basit yolu şimdi:

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

Ayrıca: class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';".
peter

11

Koşullu dönüş sınıfını yönetmek için bir işlev yapabiliriz

resim açıklamasını buraya girin

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

Ve sonra

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

Örneğin , ng-class'taki tam kod sayfasına başvurabilirsiniz


9

Angular'da yeniyim ancak sorunumu çözmek için bunu buldum:

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

Bu, şartlı olarak bir değişkene dayalı bir sınıf uygulayacaktır. Bu bir ile başlar simge ve indir varsayılan kullanılarak ng-sınıf olarak, ben durumunu kontrol showDetailseğer true/falseve sınıf uygulamak simge yükleme . Harika çalışıyor.

Umarım yardımcı olur.


9

Bu bir cazibe gibi çalışır;)

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

5

Bu muhtemelen unutulmaya indirilecek, ancak burada, tablodaki bir satırın ilk, orta veya son olmasına bağlı olarak sınıfları değiştirmek için 1.1.5'in üçlü operatörlerini nasıl kullandığım - tabloda yalnızca bir satır olması dışında:

<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

Bu benim işimde birden çok koşullu yargıç:

<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

Ng sınıfı kullanılamadığında iyi çalışan başka bir seçenek de (örneğin SVG'yi şekillendirirken):

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

(Ng-attr- kullanmak için en son dengesiz açısal olmanız gerektiğini düşünüyorum, şu anda 1.1.4'deyim)


4

iyi, doğru veya yanlış döndüren bir işlevle kontrol cihazınızdaki durumu kontrol etmenizi öneririm .

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

ve kontrol cihazınızda durumu kontrol edin

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

4

kısmi

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

kontrolör

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

3

Açısal pre v1.1.5 (yani üçlü operatör yok) kullanıyorsanız ve yine de her iki koşulda bir değer ayarlamak için eşdeğer bir yol istiyorsanız, şöyle bir şey yapabilirsiniz:

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

3

Birçok öğeye uygulanan ortak bir sınıfınız varsa, o sınıfı ng-show / ng-hide gibi ekleyecek özel bir yönerge oluşturabilirsiniz.

Bu yönerge, tıklatıldığında 'etkin' sınıfını düğmeye ekler

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

Daha fazla bilgi



3

Bunu kontrol et .

Kötü şöhretli AngularJS if|elsebildirimi !!!
Angularjs kullanmaya başladığımda, bir if / else deyimi bulamadığım için biraz şaşırdım.

Bu yüzden bir proje üzerinde çalışıyordum ve if / else deyimini kullanırken durumun yüklenirken gösterildiğini fark ettim. Bunu düzeltmek için ng-cloak kullanabilirsiniz.

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

Teşekkürler amadou


0

Bu npm paketini kullanabilirsiniz . Her şeyi idare eder ve bir değişkene veya işleve dayalı statik ve koşullu sınıflar için seçeneklere sahiptir.

// 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})} />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.