AngularJSでCSSスタイルを条件付きで適用するにはどうすればよいですか?


309

Q1。メインの「削除」ボタンが押される前に、ユーザーが削除対象としてマークした各「アイテム」の外観を変更したいとします。(この即時の視覚的フィードバックにより、ことわざの「本当によろしいですか?」ダイアログボックスが不要になります。)ユーザーはチェックボックスをオンにして、削除するアイテムを示します。チェックボックスがオフの場合、そのアイテムは通常の外観に戻るはずです。

CSSスタイルを適用または削除する最良の方法は何ですか?

Q2。各ユーザーが自分のサイトの表示方法をパーソナライズできるようにしたいとします。たとえば、フォントサイズの固定セットから選択し、ユーザー定義可能な前景色と背景色などを許可します。

ユーザーが選択/入力するCSSスタイルを適用する最良の方法は何ですか?


回答:


485

Angularは条件付き/動的にCSSスタイリングを操作するためのいくつかの組み込みディレクティブを提供します:

  • ng-class -CSSスタイルのセットが静的/事前に既知である場合に使用します
  • ng-style-スタイル値が動的に変化する可能性があるため、CSSクラスを定義できない場合に使用します。プログラム可能なスタイル値の制御を考えてください。
  • ng-showおよび ng- hide-何かを表示または非表示にするだけでよい場合に使用(CSSを変更)
  • ng- if-バージョン1.1.5の新機能。単一の条件のみを確認する必要がある場合(DOMを変更)、より詳細なng-switchの代わりに使用します。
  • ng-switch-相互に排他的な複数のng-showを使用する代わりに使用(DOMを変更)
  • ng-disabledおよび ng-readonly-フォーム要素の動作を制限するために使用します
  • ng- animate-バージョン1.1.4の新機能、CSS3トランジション/アニメーションの追加に使用

通常の「角度の方法」では、モデルの入力/操作を受け入れるUI要素にモデル/スコーププロパティを関連付け(つまり、ng-modelを使用)、そのモデルプロパティを上記の組み込みディレクティブの1つに関連付けます。

ユーザーがUIを変更すると、Angularはページ上の関連要素を自動的に更新します。


Q1はng-classの良い例のように聞こえます-CSSスタイルはクラスでキャプチャできます。

ng-classは、次のいずれかに評価される「式」を受け入れます。

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

いくつかの配列モデルでng-repeatを使用してアイテムが表示され、アイテムのチェックボックスがオンになっているときにpending-deleteクラスを適用するとします。

<div ng-repeat="item in items" ng-class="{'pending-delete': item.checked}">
   ... HTML to display the item ...
   <input type="checkbox" ng-model="item.checked">
</div>

上記では、ng-class式タイプ#3-ブール値へのクラス名のマップ/オブジェクトを使用しました。


Q2はngスタイルの良いケースのように聞こえます-CSSスタイルは動的なので、このためのクラスを定義することはできません。

ng-styleは、次のように評価する必要がある「式」を受け入れます。

  1. CSSスタイル名とCSS値のマップ/オブジェクト

不自然な例として、ユーザーが背景色のtexboxに色名を入力できると仮定します(jQueryカラーピッカーの方がはるかに便利です)。

<div class="main-body" ng-style="{color: myColor}">
   ...
   <input type="text" ng-model="myColor" placeholder="enter a color name">


上記の両方のフィドル

フィドルにはng-showng-hideの例も含まれてます。チェックボックスをオンにすると、背景色がピンクに変わるだけでなく、いくつかのテキストが表示されます。テキストボックスに「赤」を入力すると、divが非表示になります。


この答えは素晴らしいです!クリックされた要素ではない領域にクリックイベントがクラスを変更または追加した場合、jsfiddleを介して私にどのような違いがあるかを見せてもらえますか?ページの他の場所でdivと言います。
tehaaron 2013年

それは便利な記事であるtech-blog.maddyzone.com/javascript/...
Riturajラタン

素晴らしいアンサー。ところで、角度フィルタをngスタイルに適用してみたことはありますか?
Evi Song

この質問に対する最近の回答で追加したばかりのQ2に関連する追加オプションを追加することをお勧めします。
Gavin Palmer、

105

テーブル全体に1つのクラスが既に適用されている(たとえば、奇数行に色が適用されている<myClass tbody tr:nth-child(even) td>)場合に、テーブル要素内にクラスを適用すると問題が発生しました。要素をDeveloper Toolsで検査すると、にelement.styleスタイルが割り当てられていないようです。したがって、を使用する代わりに、を使用しng-classてみng-styleましたが、この場合、新しいCSS属性が内に表示されelement.styleます。このコードは私にとってはうまくいきます:

<tr ng-repeat="element in collection">

    [...amazing code...]

    <td ng-style="myvar === 0 && {'background-color': 'red'} ||
                  myvar === 1 && {'background-color': 'green'} ||
                  myvar === 2 && {'background-color': 'yellow'}">{{ myvar }}</td>

    [...more amazing code...]

</tr>

Myvarは私が評価しているものであり、myvarの値に<td>応じてそれぞれにスタイルを適用します。これにより、CSSクラスによってテーブル全体に適用された現在のスタイルが上書きされます。

更新

たとえば、ページにアクセスするときなどにテーブルにクラスを適用する場合は、次の構造を使用できます。

<li ng-class="{ active: isActive('/route_a') || isActive('/route_b')}">

基本的に、ng-classをアクティブにするために必要なのは、適用するクラスとtrueまたはfalseステートメントです。Trueはクラスを適用し、Falseは適用しません。したがって、ここではページのルートの2つのチェックとそれらの間のORがあるため、/route_a ORにいるroute_b場合、アクティブクラスが適用されます。

これは、trueまたはfalseを返す論理関数を右側に持つだけで機能します。

したがって、最初の例では、ng-styleは3つのステートメントによって条件付けられています。それらすべてがfalseの場合、スタイルは適用されませんが、ロジックに従って、少なくとも1つが適用されるため、ロジック式はどの変数比較がtrueであるかをチェックします。空でない配列は常にtrueであるため、配列を戻り値として残し、trueが1つしかない場合は、応答全体にORを使用していることを考慮して、残りのスタイルが適用されます。

ところで、私はあなたに関数isActive()を与えるのを忘れていました:

$rootScope.isActive = function(viewLocation) {
    return viewLocation === $location.path();
};

新しいアップデート

ここに私が本当に役立つと思うものがあります。変数の値に応じてクラスを適用する必要がある場合(たとえば、の内容に応じたアイコン)div、次のコードを使用できます(で非常に役立ちますng-repeat)。

<i class="fa" ng-class="{ 'fa-github'   : type === 0,
                          'fa-linkedin' : type === 1,
                          'fa-skype'    : type === 2,
                          'fa-google'   : type === 3 }"></i>

Font Awesomeのアイコン


奇妙な構文、&&は、他のcに触発された言語と同様に、ANDを意味する必要があります
Pizzaiola Gorgonzola 14年

3
@PizzaiolaGorgonzola &&はANDおよび||を意味します ORを意味します。これは、ほとんどの場合case / switchステートメントとして短絡ロジックを使用した巧妙なハックです...
Stein G. Strindhaug

ありがとうMIT。私はその詳細に気づきませんでした。
Timbergus、2015年

新しい更新セクションは魅力のように機能しました!+1してください!
Matias

New Updateで述べたng-classの例を使用して、私にはかなりうまくいきました。なめらかな
Acewin

34

これは、ng-classを使用できない場合(たとえば、SVGをスタイリングする場合)に効果的です。

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

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

AngularJS + SVGの使用に関する記事を公開しました。それはこの問題と他の多くについて話します。http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS


1.1.4ドキュメントでng-attrについての言及はありません-リンクはありますか?
Mark Rajcok 2013年

リンクがありません。申し訳ありませんが正確なページを思い出せませんが、Angularフォーラムをフォローすることでそれを知りました。
アシュレイデイビス

1
最新のドキュメント(v1.2)はng-attr-ディレクティブページのセクションngAttr属性バインディングで説明しています
Mark Rajcok 2013

1.2では、これは素晴らしい答えになります。 ng-classロジックを実行することはできませんが、実行ng-attr-classします。どちらにも用途がありますが、多くの開発者が探してng-attr-classいると思います。
Hylianpuffball 2014年

ここで提供されている他のソリューションが失敗したときに、私はこれをうまく機能させました。ありがとうございました。
dps

13
span class="circle circle-{{selectcss(document.Extension)}}">

とコード

$scope.selectcss = function (data) {
    if (data == '.pdf')
        return 'circle circle-pdf';
    else
        return 'circle circle-small';
};

CSS

.circle-pdf {
    width: 24px;
    height: 24px;
    font-size: 16px;
    font-weight: 700;
    padding-top: 3px;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
    background-image: url(images/pdf_icon32.png);
}

常にiFの言葉を避けてください
LastTribunal 15/07/27

クラス属性を直接使用しないことをお勧めします。これにより、この要素の他のプラグインによって行われた変更が上書きされます。
SimonSimCity 2017年

10

この解決策は私にとってはうまくいった

<a ng-style="{true: {paddingLeft: '25px'}, false: {}}[deleteTriggered]">...</a>

8

三項式を使用できます。これを行うには2つの方法があります。

<div ng-style="myVariable > 100 ? {'color': 'red'} : {'color': 'blue'}"></div>

または...

<div ng-style="{'color': (myVariable > 100) ? 'red' : 'blue' }"></div>

1
多分あなたはそれをより良く見つけるでしょう:<div ng-style = "{'color':(myVariable> 100)? 'red': 'blue'}"> </ div>
Dudi

Dudiは、それよりも良くても、同じくらい便利なので、@ maykelの「3項式」の回答に追加しました。二人ともありがとう!
jbobbins '19年

7

1つまたは2つのプロパティの単純なCSSスタイルが必要な場合の別のオプション:

見る:

<tr ng-repeat="element in collection">
    [...amazing code...] 
    <td ng-style="{'background-color': getTrColor(element.myvar)}">
        {{ element.myvar }}
    </td>
    [...more amazing code...]
</tr>

コントローラ:

$scope.getTrColor = function (colorIndex) {
    switch(colorIndex){
        case 0: return 'red';
        case 1: return 'green';
        default: return 'yellow';
    }
};

6

次の例を参照してください

<!DOCTYPE html>
    <html ng-app>
    <head>
    <title>Demo Changing CSS Classes Conditionally with Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
    <script src="res/js/controllers.js"></script>

    <style>

    .checkboxList {
        border:1px solid #000;
        background-color:#fff;
        color:#000;
        width:300px;
        height: 100px;
        overflow-y: scroll;
    }

    .uncheckedClass {
       background-color:#eeeeee;
       color:black;
    }
    .checkedClass {
        background-color:#3ab44a;
        color:white;
    }
    </style>

    </head>
    <body ng-controller="TeamListCtrl">
    <b>Teams</b>
    <div id="teamCheckboxList" class="checkboxList">

    <div class="uncheckedClass" ng-repeat="team in teams" ng-class="{'checkedClass': team.isChecked, 'uncheckedClass': !team.isChecked}">

    <label>
    <input type="checkbox" ng-model="team.isChecked" />
    <span>{{team.name}}</span>
    </label>
    </div>
    </div>
    </body>
    </html>

2

AngularJS v1.2.0rc以降、SVG要素ng-classng-attr-class失敗することさえあります(クラス属性内の通常のバインディングでも、以前は機能していました)

具体的には、これらのどれも現在は機能しません。

ng-class="current==this_element?'active':' ' "
ng-attr-class="{{current==this_element?'active':' '}}"
class="class1 class2 .... {{current==this_element?'active':''}}"

回避策として、私は使用しなければなりません

ng-attr-otherAttr="{{current==this_element?'active':''}}"

そして、スタイルを使用して

[otherAttr='active'] {
   ... styles ...
}

1

スタイルを条件付きで適用するもう1つの(将来の)方法は、スコープ付きスタイルを条件付きで作成することです。

<style scoped type="text/css" ng-if="...">

</style>

しかし、現在、FireFoxだけがスコープ付きスタイルをサポートしています。


1

私が最近発見したもう1つのオプションがあります。スタイル要素内のCSSルールを変更できるため、ng-style、ng-classなどの角度ディレクティブを繰り返し使用する必要がなくなるため、一部の人々が便利だと感じるかもしれません。 ng-show、ng-hide、ng-animateなど。

このオプションは、コントローラーによって設定され、「カスタムスタイル」と呼ぶ属性ディレクティブによって監視されるサービス変数を使用してサービスを利用します。この戦略はさまざまな方法で使用でき、私はこのフィドルでいくつかの一般的なガイダンスを提供しようとしました。

var app = angular.module('myApp', ['ui.bootstrap']);
app.service('MainService', function(){
    var vm = this;
});
app.controller('MainCtrl', function(MainService){
    var vm = this;
    vm.ms = MainService;
});
app.directive('customStyle', function(MainService){
    return {
        restrict : 'A',
        link : function(scope, element, attr){
            var style = angular.element('<style></style>');
            element.append(style);
            scope.$watch(function(){ return MainService.theme; },
                function(){
                    var css = '';
                    angular.forEach(MainService.theme, function(selector, key){
                        angular.forEach(MainService.theme[key], function(val, k){
                            css += key + ' { '+k+' : '+val+'} ';
                        });                        
                    });
                    style.html(css);
                }, true);
        }
    };
});

1

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

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

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

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

0

注意すべき点の1つは、CSSスタイルにダッシュがある場合、それらを削除する必要があることです。したがって、を設定するbackground-color場合、正しい方法は次のとおりです。

ng-style="{backgroundColor:myColor}" 

5
いいえ、必要はありません。ng-style = "{'background-color':myColor}"は完璧に機能します。
ゲラサルス2014

0

無効なボタンに灰色のテキストスタイルを条件付きで適用する方法は次のとおりです

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  styleUrls: [ './app.component.css' ],
  template: `
  <button 
    (click)='buttonClick1()' 
    [disabled] = "btnDisabled"
    [ngStyle]="{'color': (btnDisabled)? 'gray': 'black'}">
    {{btnText}}
  </button>`
})
export class AppComponent  {
  name = 'Angular';
  btnText = 'Click me';
  btnDisabled = false;
  buttonClick1() {
    this.btnDisabled = true;
    this.btnText = 'you clicked me';
    setTimeout(() => {
      this.btnText = 'click me again';
      this.btnDisabled = false
      }, 5000);
  }
}

これが実際の例です:https :
//stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html

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