Jak warunkowo zastosować style CSS w AngularJS?

Q1. Załóżmy, że chcę zmienić wygląd każdego "elementu", który użytkownik zaznacza do usunięcia przed naciśnięciem głównego przycisku" Usuń". (Owo natychmiastowe wizualne sprzężenie zwrotne powinno eliminować potrzebę przysłowiowego " are you sure?"okno dialogowe.) Użytkownik zaznaczy pola wyboru, aby wskazać, które elementy należy usunąć. Jeśli pole wyboru nie jest zaznaczone, element powinien powrócić do normalnego wyglądu.

Jaki jest najlepszy sposób na zastosowanie lub usunięcie stylizacji CSS?

Q2. Załóżmy, że chcę pozwól każdemu użytkownikowi spersonalizować sposób prezentacji mojej strony. Na przykład, Wybierz ze stałego zestawu rozmiarów czcionek, Zezwalaj na definiowane przez użytkownika kolory pierwszego planu i tła itp.

Jaki jest najlepszy sposób na zastosowanie stylów CSS, które użytkownik wybiera / wprowadza?

 299
Author: Mark Rajcok, 2012-12-11

13 answers

Angular dostarcza szereg wbudowanych dyrektyw do warunkowego / dynamicznego manipulowania stylami CSS:

  • klasa ng - Użyj, gdy zestaw stylów CSS jest statyczny / znany przed czasem
  • ng-style - Użyj, gdy nie możesz zdefiniować klasy CSS, ponieważ wartości stylów mogą zmieniać się dynamicznie. Pomyśl o programowalnej kontroli wartości stylu.
  • ng-show oraz ng-hide - używaj tylko wtedy, gdy trzeba coś pokazać lub ukryć (modyfikuje CSS)
  • ng-if - nowy w wersji 1.1.5, użyj zamiast bardziej wyrazistego ng-switch, jeśli chcesz tylko sprawdzić pojedynczy warunek (modyfikuje DOM)
  • ng-switch - użyj zamiast używania kilku wzajemnie wykluczających się ng-shows (modyfikuje DOM)
  • ng-niepełnosprawni oraz ng-readonly - Użyj do ograniczenia elementu formularza zachowanie
  • ng-animate - nowy w wersji 1.1.4, Użyj, aby dodać przejścia/animacje CSS3

Normalna "droga kątowa" polega na powiązaniu właściwości modelu / scope z elementem interfejsu użytkownika, który akceptuje wprowadzanie / manipulację użytkownika (tj. używa ng-model), a następnie powiązaniu tej właściwości modelu z jedną z wbudowanych dyrektyw wymienionych powyżej.

Gdy użytkownik zmieni interfejs, Angular automatycznie zaktualizuje powiązane elementy na strona.


Q1 brzmi jak dobry przykład dla ng-class -- styl CSS może być uchwycony w klasie.

Ng-class akceptuje "wyrażenie", które musi oceniać do jednego z następujących:

  1. łańcuch nazw klas rozdzielonych spacjami
  2. Tablica nazw klas
  3. Mapa / obiekt nazw klas do wartości logicznych

Zakładając, że twoje elementy są wyświetlane za pomocą ng-repeat nad jakimś modelem tablicy, i że gdy pole wyboru dla elementu jest zaznaczono, że chcesz zastosować klasę 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>

Powyżej użyliśmy wyrażenia klasy ng typu #3-mapy / obiektu nazw klas do wartości logicznych.


Q2 brzmi jak dobry przykład dla ng-style -- styl CSS jest dynamiczny, więc nie możemy zdefiniować dla tego klasy.

Ng-style akceptuje "wyrażenie", które musi oceniać Do:

  1. Mapa / obiekt stylu CSS nazwy do wartości CSS

Dla wymyślonego przykładu, załóżmy, że użytkownik może wpisać Nazwa koloru w texboxie dla koloru tła (próbnik koloru jQuery byłby o wiele ładniejszy):

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


Fiddle dla obu powyższych.

Fiddle zawiera również przykład ng-showi ng-hide. Jeśli zaznaczone jest pole wyboru, oprócz koloru tła zmieniającego kolor na różowy, wyświetlany jest jakiś tekst. Jeśli w polu tekstowym zostanie wprowadzony "czerwony", div zostanie ukryty.

 472
Author: Mark Rajcok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-25 13:33:14

Znalazłem problemy przy stosowaniu klas wewnątrz tabeli elementów, gdy jedna klasa została już zastosowana do całej tabeli (na przykład kolor zastosowany do nieparzystych wierszy <myClass tbody tr:nth-child(even) td>). Wygląda na to, że gdy sprawdzasz element za pomocą narzędzi programistycznych , element.style nie ma przypisanego stylu. Zamiast używać ng-class, próbowałem użyć ng-style i w tym przypadku nowy atrybut CSS pojawia się wewnątrz element.style. Ten kod działa dla mnie świetnie:

<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 jest co oceniam i w każdym przypadku stosuję styl do każdej <td>w zależności od wartości myvar, który nadpisuje bieżący styl zastosowany przez klasę CSS dla całej tabeli.

UPDATE

Jeśli chcesz zastosować klasę do tabeli, na przykład podczas odwiedzania strony lub w innych przypadkach, możesz użyć tej struktury:

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

Zasadniczo, to, czego potrzebujemy do aktywacji klasy ng, to klasa do zastosowania i prawdziwe lub fałszywe oświadczenie. True stosuje klasę, A false nie. więc tutaj mamy dwa sprawdzania trasy strony i lub pomiędzy nimi, więc jeśli jesteśmy w /route_a lub jesteśmy w route_b, zostanie zastosowana klasa active.

To działa po prostu mając funkcję logiczną po prawej stronie, która zwraca true lub false.

Więc w pierwszym przykładzie, ng-style jest uwarunkowane trzema stwierdzeniami. Jeśli wszystkie z nich są fałszywe, nie stosuje się żadnego stylu, ale zgodnie z naszą logiką, co najmniej jedna zostanie zastosowana, więc wyrażenie logiczne sprawdzi, które porównanie zmiennych jest prawdziwe, a ponieważ nie pusta tablica jest zawsze prawdziwa, która pozostawi tablicę jako zwrot i tylko z jedną prawdą, biorąc pod uwagę, że używamy lub dla całej odpowiedzi, zastosowany zostanie pozostały styl.

Przy okazji, zapomniałem podać funkcję isActive ():

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

NOWA AKTUALIZACJA

Tutaj masz coś, co znalazłem naprawdę przydatne. Gdy musisz zastosować klasę zależną od wartości zmiennej, na przykład ikonę zależną od zawartości div, możesz użyć następującego kodu (bardzo przydatnego w 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 from Font Awesome

 103
Author: Timbergus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-30 15:55:37

To działa dobrze, gdy nie można użyć ng-class (na przykład podczas stylizacji SVG):

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

(myślę, że musisz być na najnowszym unstable Angular, aby użyć ng-attr -, obecnie jestem na 1.1.4)

Opublikowałem artykuł na temat pracy z AngularJS + SVG. Mówi o tym problemie i wielu innych. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

 34
Author: Ashley Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-19 07:14:53
span class="circle circle-{{selectcss(document.Extension)}}">

I Kod

$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
Author: Nenad Jesic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-31 12:03:33

To rozwiązanie mi pomogło

<a ng-style="{true: {paddingLeft: '25px'}, false: {}}[deleteTriggered]">...</a>
 10
Author: iamtankist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-23 19:25:32

Inna opcja, gdy potrzebujesz prostego stylu css z jedną lub dwiema właściwościami:

Widok:

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

Kontroler:

$scope.getTrColor = function (colorIndex) {
    switch(colorIndex){
        case 0: return 'red';
        case 1: return 'green';
        default: return 'yellow';
    }
};
 7
Author: Dudi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-23 08:23:24

Możesz użyć wyrażenia trójkowego. Można to zrobić na dwa sposoby:

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

Lub...

<div ng-style="{'color': (myVariable > 100) ? 'red' : 'blue' }"></div>
 7
Author: michal-michalak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-27 05:24:11

Zobacz następujący przykład

<!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
Author: Ranga Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-13 06:58:16

Od AngularJS v1.2.0 rc, ng-class a nawet ng-attr-class nie działają z elementami SVG (działały wcześniej, nawet z normalnym wiązaniem wewnątrz atrybutu klasy)

W szczególności, żadne z nich nie działa teraz:

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

Jako obejście muszę użyć

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

A następnie style używając

[otherAttr='active'] {
   ... styles ...
}
 2
Author: kumar_harsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-15 12:48:33

Jeszcze jeden (w przyszłości) sposób warunkowego stosowania stylu jest poprzez warunkowe tworzenie stylu scoped

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

</style>

Ale obecnie tylko FireFox obsługuje style scoped.

 1
Author: Pavel Voronin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-19 13:39:29

Jest jeszcze jedna opcja, którą niedawno odkryłem, że niektórzy ludzie mogą uznać za przydatną, ponieważ pozwala ona zmienić regułę CSS w elemencie stylu - unikając w ten sposób potrzeby wielokrotnego używania dyrektywy kątowej, takiej jak ng-style, ng-class, ng-show, ng-hide, ng-animate i innych.

Ta opcja wykorzystuje usługę ze zmiennymi service, które są ustawiane przez kontroler i nadzorowane przez atrybut-dyrektywę, którą nazywam "custom-style". Strategia ta może być stosowana w wielu różne sposoby, a ja starałem się zapewnić ogólne wskazówki z tym .

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
Author: Gavin Palmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-07 14:28:05

Sugerowałbym sprawdzenie warunku w kontrolerze za pomocą funkcji zwracającej true lub false .

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

I w kontrolerze sprawdź stan

$scope.getTodayForHighLight = function(today, date){
    return (today == date);
}
 1
Author: sheelpriy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-27 05:24:37

Jedną rzeczą do obejrzenia jest - jeśli styl CSS ma myślniki - musisz je usunąć. Więc jeśli chcesz ustawić background-color, poprawnym sposobem jest:

ng-style="{backgroundColor:myColor}" 
 0
Author: Neil Munro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-05 11:04:57