wake-up-neo.com

Wie wende ich CSS-Stile in AngularJS bedingt an?

Q1. Angenommen, ich möchte das Aussehen jedes "Elements" ändern, das ein Benutzer zum Löschen markiert, bevor der Hauptknopf "Löschen" gedrückt wird. (Dieses sofortige visuelle Feedback sollte das sprichwörtliche Dialogfeld "Sind Sie sicher?" Überflüssig machen.) Der Benutzer aktiviert die Kontrollkästchen, um anzugeben, welche Elemente gelöscht werden sollen. Wenn ein Kontrollkästchen nicht markiert ist, sollte das Element wieder normal aussehen.

Wie kann ich das CSS-Styling am besten anwenden oder entfernen?

Q2. Angenommen, ich möchte, dass jeder Benutzer die Darstellung meiner Website personalisieren kann. Zum Beispiel können Sie aus einem festen Satz von Schriftgrößen auswählen, vom Benutzer definierbare Vorder- und Hintergrundfarben usw. zulassen.

Was ist der beste Weg, um den CSS-Stil anzuwenden, den der Benutzer auswählt/eingibt?

301
Mark Rajcok

Angular bietet eine Reihe von integrierten Anweisungen zum bedingten/dynamischen Manipulieren von CSS-Stilen:

  • NG-CLASS - Wird verwendet, wenn der Satz von CSS-Stilen statisch ist/im Voraus bekannt ist
  • NG-STYLE - Verwenden Sie diese Option, wenn Sie keine CSS-Klasse definieren können, da sich die Stilwerte möglicherweise dynamisch ändern. Denken Sie an eine programmierbare Steuerung der Stilwerte.
  • NG-SHOW und NG-HIDE - Verwenden Sie diese Option, wenn Sie nur etwas anzeigen oder ausblenden müssen (ändert CSS).
  • NG-IF - neu in Version 1.1.5. Verwenden Sie anstelle des ausführlicheren Befehls "ng-switch", wenn Sie nur nach einer einzelnen Bedingung suchen müssen (ändert DOM).
  • NG-SWITCH - statt mehrere sich gegenseitig ausschließende ng-shows verwenden (ändert DOM)
  • NG-DISABLED und NG-READONLY - verwenden, um das Verhalten von Formularelementen zu beschränken
  • NG-ANIMATE - neu in Version 1.1.4. Zum Hinzufügen von CSS3-Übergängen/-Animationen

Der normale "winkelige Weg" beinhaltet das Verknüpfen einer Modell-/Geltungsbereichseigenschaft mit einem UI-Element, das eine Benutzereingabe/-manipulation akzeptiert (d. H. Use ng-model), und anschließend diese Modelleigenschaft einer der oben genannten eingebauten Anweisungen zuordnet. 

Wenn der Benutzer die Benutzeroberfläche ändert, aktualisiert Angular die zugehörigen Elemente auf der Seite automatisch.


Q1 klingt nach einem guten Argument für ng-class - das CSS-Styling kann in einer Klasse erfasst werden.

ng-class akzeptiert einen "Ausdruck", der eine der folgenden Bedingungen auswerten muss:

  1. eine Zeichenfolge mit durch Leerzeichen getrennten Klassennamen
  2. ein Array von Klassennamen
  3. eine Karte/ein Objekt mit Klassennamen und booleschen Werten

Angenommen, Ihre Elemente werden mit ng-repeat über einem Array-Modell angezeigt. Wenn das Kontrollkästchen für ein Element aktiviert ist, möchten Sie die Klasse pending-delete anwenden:

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

Oben haben wir ng-class expression type # 3 verwendet - eine Map/ein Objekt mit Klassennamen und booleschen Werten.


Q2 klingt nach einem guten Argument für ng-style - das CSS-Styling ist dynamisch, daher können wir keine Klasse dafür definieren.

ng-style akzeptiert einen "Ausdruck", der Folgendes auswerten muss:

  1. eine Karte/ein Objekt mit CSS-Stilnamen zu CSS-Werten

Angenommen, der Benutzer kann einen Farbnamen in eine Textbox für die Hintergrundfarbe eingeben (ein jQuery-Farbwähler wäre viel schöner):

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


Fiddle für beide der oben genannten.

Die Geige enthält auch ein Beispiel für ng-show und ng-hide. Wenn ein Kontrollkästchen aktiviert ist, wird zusätzlich zu der Hintergrundfarbe, die rosa wird, Text angezeigt. Wenn "rot" in das Textfeld eingegeben wird, wird ein Div ausgeblendet.

476
Mark Rajcok

Ich habe Probleme beim Anwenden von Klassen in table - Elementen gefunden, wenn bereits eine Klasse auf die gesamte Tabelle angewendet wurde (z. B. eine Farbe auf die ungeraden Zeilen <myClass tbody tr:nth-child(even) td>). Es scheint, dass, wenn Sie das Element mit Developer Tools untersuchen, dem element.style kein Stil zugewiesen ist. Anstatt ng-class zu verwenden, habe ich versucht, ng-style zu verwenden, und in diesem Fall erscheint das neue CSS-Attribut in element.style. Dieser Code funktioniert gut für mich:

<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 bewerte ich, und in jedem Fall wende ich für jeden <td> einen Stil an, abhängig vom myvar -Wert, der den aktuellen Stil überschreibt, der von der CSS-Klasse für die gesamte Tabelle angewendet wird.

UPDATE

Wenn Sie beispielsweise auf eine Seite oder in anderen Fällen eine Klasse auf die Tabelle anwenden möchten, können Sie diese Struktur verwenden:

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

Grundsätzlich benötigen wir zur Aktivierung einer ng-class die anzuwendende Klasse und eine True- oder False-Anweisung. True wendet die Klasse an und false nicht. Hier haben wir also zwei Überprüfungen der Route der Seite und ein ODER zwischen ihnen. Wenn wir also in /route_aODER sind, befinden wir uns in route_b, die Klasse active angewendet werden.

Dies funktioniert nur mit einer Logikfunktion auf der rechten Seite, die wahr oder falsch zurückgibt.

Im ersten Beispiel wird ng-style von drei Anweisungen konditioniert. Wenn alle falsch sind, wird kein Stil angewendet. In Übereinstimmung mit unserer Logik wird jedoch mindestens einer angewendet. Der Logikausdruck überprüft also, welcher Variablenvergleich wahr ist. Da ein nicht leeres Array immer wahr ist, wird dies der Fall sein Ein Array als Rückgabewert hinterlassen, und mit nur einem einzigen Wert. Wenn Sie für die gesamte Antwort ODER verwenden, wird der verbleibende Stil angewendet.

Ich habe übrigens vergessen, dir die Funktion isActive () zu geben:

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

NEUES UPDATE

Hier haben Sie etwas, das ich wirklich nützlich finde. Wenn Sie eine Klasse abhängig vom Wert einer Variablen anwenden müssen, z. B. ein Symbol, das vom Inhalt der div abhängt, können Sie den folgenden Code verwenden (sehr nützlich in ng-repeat):

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

Icons von Font Awesome

105
Timbergus

Dies funktioniert gut, wenn ng-class nicht verwendet werden kann (zum Beispiel beim SVG-Styling):

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

(Ich denke, du musst auf dem neuesten instabilen Angular sein, um ng-attr- verwenden zu können, ich bin derzeit auf 1.1.4.)

Ich habe einen Artikel über die Arbeit mit AngularJS + SVG veröffentlicht. Es spricht über dieses Thema und zahlreiche andere. http://www.codeproject.com/Articles/709340/Implementierung-a-Flowchart-mit-SVG-und-AngularJS

34
Ashley Davis
span class="circle circle-{{selectcss(document.Extension)}}">

und Code

$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);
}
12
Nenad Jesic

Diese Lösung hat mir geholfen

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

Eine weitere Option, wenn Sie einen einfachen CSS-Stil mit einer oder zwei Eigenschaften benötigen:

Aussicht:

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

Regler:

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

Sie können einen ternären Ausdruck verwenden. Es gibt zwei Möglichkeiten, dies zu tun:

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

oder...

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

Siehe folgendes Beispiel

<!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>
6
Ranga Reddy

Seit AngularJS v1.2.0rc schlagen ng-class und sogar ng-attr-class mit SVG-Elementen fehl (sie funktionierten früher, selbst mit normaler Bindung im Klassenattribut)

Im Einzelnen funktioniert jetzt keiner von diesen:

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

Als Workaround muss ich verwenden 

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

und dann mit formatieren

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

nun, ich würde Ihnen vorschlagen, den Zustand in Ihrem Controller mit einer Funktion zu überprüfen, die true oder false liefert.

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

und überprüfen Sie in Ihrem Controller den Zustand 

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

Eine weitere Möglichkeit (in Zukunft), den Stil bedingt anzuwenden, besteht darin, einen bereichsabhängigen Stil zu erstellen

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

</style>

Heutzutage unterstützt nur FireFox Scope.

1
Pavel Voronin

Ich habe kürzlich eine weitere Option entdeckt, die für manche Benutzer nützlich sein könnte, da sie es Ihnen ermöglicht, eine CSS-Regel innerhalb eines style-Elements zu ändern. ng-show, ng-hide, ng-animieren und andere.

Diese Option verwendet einen Dienst mit Dienstvariablen, die von einem Controller festgelegt und von einer Attribut-Direktive überwacht werden, die ich als "benutzerdefinierten Stil" bezeichne. Diese Strategie kann auf viele verschiedene Arten verwendet werden, und ich habe versucht, mit dieser Geige einige allgemeine Hinweise zu geben.

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

Beachten Sie Folgendes: Wenn der CSS-Stil Bindestriche enthält, müssen Sie diese entfernen. Wenn Sie also background-color einstellen möchten, lautet der korrekte Weg:

ng-style="{backgroundColor:myColor}" 
0
Neil Munro

So habe ich den grauen Textstil auf einen deaktivierten Button angewendet

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

Hier ist ein Arbeitsbeispiel:
https://stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html

0
BraveNewMath