クラスを条件付きで適用する最良の方法は何ですか?


1183

あなたがでレンダリングされたアレイ考えてみましょうulとのli各要素と呼ばれるコントローラのプロパティのためにselectedIndex。AngularJS liのインデックスselectedIndexでクラスを追加する最良の方法は何でしょうか?

私は現在、liコードを(手動で)複製し、liタグの1つにクラスを追加し、インデックスごとに1 つだけを使用ng-showng-hideて表示していliます。


2
この質問への回答は、テンプレートには{{varname}}よりも多くのものがあることを示しています。いくつかの異なる形式の3項演算子など、テンプレートの詳細についてのドキュメントはどこにありますか?docs.angularjs.org/guide/templatesは、{{varname.fieldname}}の他に、条件などに関してテンプレートが提供するものを説明していないようです。
Christos Hayward

私はそれはあなたのために働くことを願っていますため、これはとても便利ですドロドロtech-blog.maddyzone.com/javascript/...
Riturajラタン

回答:


1384

私のように、CSSクラス名をコントローラーに入れたくない場合は、v1以前から使用していた古いトリックを以下に示します。選択したクラス名に直接評価される式を記述できます。カスタムディレクティブは必要ありません。

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

コロン付きの古い構文に注意してください。

次のように、クラスを条件付きで適用する新しいより良い方法もあります。

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

Angularはオブジェクトを返す式をサポートするようになりました。このオブジェクトの各プロパティ(名前)はクラス名と見なされ、その値に応じて適用されます。

ただし、これらの方法は機能的に同等ではありません。次に例を示します。

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

したがって、基本的にモデルプロパティをクラス名にマッピングすることで既存のCSSクラスを再利用すると同時に、CSSクラスをコントローラーコードに含めないようにすることができます。


33
OP、それは私が今まで見た三項演算子を表現するためのより悪い方法かもしれません。検討しました($index==selectedIndex) ? 'selected' : ''か?
Malvolio

17
@Malvolio AFAIR、3項演算子がv0.9.xの角度式内で機能しませんでした。これは多かれ少なかれスイッチです。
orcun

36
ng-class(2012年1月19日現在)は、1)スペース区切りのクラス名の文字列、または2)クラス名の配列、または3)クラスのマップ/オブジェクトのいずれかに評価される式をサポートするようになりました名前をブール値に。したがって、3)を使用:ng-class = "{selected:$ index == selectedIndex}"
Mark Rajcok '28

2
ところで、@ Markに感謝します。確認したところで、このメソッドはv1で機能していると言えます。それはまだいくつかの場合に役立ちます。オブジェクトのプロパティ名(キー)は必ずしもtrueまたはfalseである必要はなく、クラス名にマップしたいものであれば何でもかまいません。
orcun 2012

6
追加したいのですが、のような構文を使用して{classname: '$index === selectedIndex'} いて機能しなかったため、問題が発生し ました。すべてをまとめて、===の代わりに==を使用すると、うまくいきました。 {classname: '$index==selectedIndex'}
Lucas

437

ngクラスは、次のいずれかに評価される必要がある式をサポートします

  1. スペースで区切られたクラス名の文字列、または
  2. クラス名の配列、または
  3. ブール値へのクラス名のマップ/オブジェクト。

したがって、フォーム3)を使用して、次のように簡単に記述できます。

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

AngularJSでCSSスタイルを条件付きで適用する方法も参照してくださいより広い答えのために。


更新:Angular 1.1.5は三項演算子のサポートを追加しました。

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

2
3項演算子の+1(今は1つ必要です)ですが、1.1。*は「不安定なリリース」であり、APIは入力時の時点で予告なく変更される可能性があります。1.0。*は安定しているので、来週6か月間プロジェクトを展開する場合は、これを使用するほうが快適です。
Dave Everitt 2013年

1
ng-class="{'selected': $index==selectedIndex}"私のために働く
knuhol

160

私の好きな方法は三項式を使うことです。

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

注:古いバージョンのAngularを使用している場合は、代わりにこれを使用してください。

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

2
これは私がこの表現を書くのに役立ちました:ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}"。他の方法を理解できませんでした。
dduft 2015年

スコープ付きブールmodalFlagが更新されない理由が本当にわかりません-ng-class = "{'closed':modalFlag、 'open':!modalFlag}"スコープ付き変数/ブールに応じてクローズまたはオープンのいずれかを追加しようとしています-誰かが私を助けることができれば私は非常に感謝します-ありがとう。
着陸

これは1.5バージョンとして導入されました。github.com/angular/angular.js/commit/...
Mubashir Koul

55

これらの回答の一部が古くなっているように見えるので、これを追加します。ここに私がそれをする方法があります:

<class="ng-class:isSelected">

ここで、「isSelected」はスコープ付き角度コントローラー内で定義されたJavaScript変数です。


より具体的にあなたの質問に対処するために、これを使用してリストを生成する方法を次に示します。

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


見る: http //jsfiddle.net/tTfWM/

参照:http : //docs.angularjs.org/api/ng.directive : ngClass


クラス=の間にいただきましたが貴様"NG-クラス:item.isSelected"とNG-クラス= "item.isSelected"
zloctb

ng-class:classNamevs の使用に興味がありますclass="{{className}}"か?
Roi

48

これははるかに簡単な解決策です:

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
コントローラにCSSの要素を近づけないことを強くお勧めします。それはあなたが下りたくない道です。
リバイアサン2012

1
テンプレートに含まれるクラス名
Casey

5
ある時点で、jsfiddleは請求書の支払いを逃したり、別のドメインに移動したりすることがあります。そうしないと、責任者がバスで殺されます(バスファクターも参照)。だから、私はあなたにそのフィドルが何をするかをあなたの答えの中で説明するように頼むことができますか?これはスタックオーバーフローでも標準的です。
セバスチャンマッハ

27

私は最近同様の問題に直面し、条件付きフィルターを作成することにしました:

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

2つの要素の配列または文字列のいずれかである単一の引数を取り、2番目の要素として空の文字列が追加された配列に変換されます。

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

1
例として、ブール値1 o 0に応じてクラス 'yes'または 'no'を返すyesNo()フィルターを作成したところ:filter('yesNo', function() { return function(input) { // info('yesNo('+ input +')'); switch(input){ case '1': return ' yes '; break; default: return ' no '; break; } } });
svassr

1
ng-classはクラス名のマップ/オブジェクトをブール値に処理できるため、次のように簡単に記述できます。ng-class = "{yes:some_boolean_expression、no:some_other_boolean_expression}" Eg、ng-class = "{yes:input 、いいえ:!input} "
Mark Rajcok 2012

21

バイナリ評価を超えて、CSSをコントローラーの外に置きたい場合は、マップオブジェクトに対して入力を評価する単純なフィルターを実装できます。

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

これにより、次のようにマークアップを記述できます。

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

こんにちは@ Joe、null値を処理するためのアイデアはありますか?入力にnullを渡すと、そのクラスはマップされません...
dalcam

1
@ user1191559-「デフォルト」のアイテムをマップに入れ、「入力」がnullの場合はその値を返すことができます。
ジョースティール2014

17

私が最近やったことはこれをやっていた:

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

isShowing値は、ボタンのクリックで切り替えると、単一の括弧の間の部分は、私は私のCSSファイルで作成したクラスですます私のコントローラ上に配置されている値です。

編集:私はまた、codeschool.comに、AngularJSのgoogleがスポンサーとなっている無料コースを追加したいと思います。何も支払う必要はなく、アカウントにサインアップして始めましょう!幸運を祈ります!


ここにフィドル以上のコードを提供できますか?あるisShowingコントローラ内の配列?
カイル・ペネル2014

ブール値だと思います
ミルコ

15

Ternaryオペレーター1.1.5で Angular Parserに追加れました。

したがって、これを行う最も簡単な方法は次のとおりです。

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

また:class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';"
ピーター2013

11

条件付きの戻りクラスを管理する関数作成できます

ここに画像の説明を入力してください

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

その後

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

例の場合ng-classで完全なコードページを参照できます。


9

Angularは初めてですが、問題を解決するためにこれを見つけました。

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

これは、varに基づくクラスを条件付きで適用します。それはで始まるアイコンのダウンロードデフォルト、使用してNG-クラスとして、私はステータスチェックshowDetailsの場合にtrue/false、クラス適用アイコンアップロード。その素晴らしい仕事。

それが役に立てば幸い。


9

これは魅力のように機能します;)

<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

これはおそらく忘却への反対投票になるでしょうが、これは私が1.1.5の三項演算子を使用して、テーブル内の行が最初、中間、または最後であるかどうかに応じてクラスを切り替える方法です(テーブルに行が1つしかない場合を除く)。

<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

これは私の仕事で複数の条件付き裁判官です:

<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-classを使用できない場合にうまく機能する別のオプションを次に示します(たとえば、SVGをスタイリングする場合)。

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

(ng-attr-を使用するには、最新の不安定なAngularを使用する必要があると思います。現在1.1.4を使用しています)


4

まあ私はあなたがtrueまたはfalseを返す関数であなたのコントローラーの状態をチェックすることをお勧めします。

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

そしてあなたのコントローラーで状態をチェックしてください

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

4

部分的

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

コントローラ

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

3

angular pre v1.1.5 (つまり、3項演算子なし)を使用していて、両方の条件で値を設定する同等の方法が必要な場合は、次のようにすることができます。

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

3

多くの要素に適用される共通のクラスがある場合は、ng-show / ng-hideのようなそのクラスを追加するカスタムディレクティブを作成できます。

このディレクティブは、クリックされた場合、ボタンに「アクティブ」クラスを追加します

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

より詳しい情報


3

多くの検索の後に、今日私に役立つ何かを追加するだけです...

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

これが開発の成功に役立つことを願っています。

=)

文書化されていない式の構文:素晴らしいウェブサイトリンク... =)


受け入れられた答えを確認してください。同じことを行っており、より多くの例を示しています。
respectTheCode

3

これを確認してください。

悪名高いAngularJS if|elseステートメント!!!
Angularjsを使い始めたとき、if / elseステートメントが見つからないことに少し驚きました。

だから私はプロジェクトに取り組んでいて、if / elseステートメントを使用すると、ロード中に条件が表示されることに気付きました。ng-cloakを使用してこれを修正できます。

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

ありがとうamadou


0

この npmパッケージを使用できます。すべてを処理し、変数または関数に基づく静的および条件付きクラスのオプションがあります。

// 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})} />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.