Come faccio a applicare in modo condizionale gli stili CSS in AngularJS?

Q1. Supponiamo di voler modificare l’aspetto di ciascun “elemento” che un utente contrassegna per l’eliminazione prima che venga premuto il pulsante principale “Elimina”. (Questo feedback visivo immediato dovrebbe eliminare la necessità della proverbiale finestra di dialogo “Sei sicuro?”). L’utente controllerà le caselle di controllo per indicare quali elementi devono essere eliminati. Se una casella è deselezionata, quell’elemento dovrebbe tornare al suo aspetto normale.

Qual è il modo migliore per applicare o rimuovere lo stile CSS?

Q2. Supponiamo che voglio consentire a ciascun utente di personalizzare come viene presentato il mio sito. Ad esempio, seleziona da un set fisso di dimensioni dei caratteri, consenti i colors di primo piano e di sfondo definibili dall’utente, ecc.

Qual è il modo migliore per applicare lo stile CSS che l’utente seleziona / input?

Angular fornisce una serie di direttive incorporate per manipolare lo stile CSS in modo condizionale / dinamico:

  • ng-class – usa quando il set di stili CSS è statico / conosciuto in anticipo
  • ng-style – usa quando non puoi definire una class CSS perché i valori di stile possono cambiare dynamicmente. Pensa al controllo programmabile dei valori di stile.
  • ng-show e ng-hide – usa se hai solo bisogno di mostrare o hide qualcosa (modifica CSS)
  • ng-if – nuovo nella versione 1.1.5, usa invece il più ng-switch più dettagliato se hai solo bisogno di verificare una singola condizione (modifica DOM)
  • ng-switch – usa invece di usare diversi ng show mutuamente esclusivi (modifica DOM)
  • ng-disabled e ng-readonly : utilizzare per limitare il comportamento dell’elemento del modulo
  • ng-animate – nuovo nella versione 1.1.4, utilizzato per aggiungere transizioni / animazioni CSS3

Il normale “modo angular” consiste nel bind una proprietà model / scope a un elemento dell’interfaccia utente che accetterà input / manipolazione dell’utente (cioè, usa ng-model) e quindi assocerà quella proprietà del modello a una delle direttive incorporate menzionate sopra.

Quando l’utente cambia l’interfaccia utente, Angular aggiornerà automaticamente gli elementi associati nella pagina.


Q1 sembra un buon caso per la class ng: lo stile CSS può essere catturato in una class.

ng-class accetta una “espressione” che deve valutare uno dei seguenti:

  1. una stringa di nomi di classi delimitati da spazio
  2. una serie di nomi di classi
  3. una mappa / object di nomi di classi in valori booleani

Supponendo che i tuoi articoli vengano visualizzati usando ng-repeat su un modello di array e che quando la casella di controllo per un object è selezionata, vuoi applicare la class di pending-delete :

 
... HTML to display the item ...

Sopra, abbiamo usato il tipo di espressione ng-class # 3 – una mappa / object di nomi di classi in valori booleani.


Q2 sembra un buon caso per ng-style – lo stile CSS è dinamico, quindi non possiamo definire una class per questo.

ng-style accetta una “espressione” che deve valutare:

  1. una mappa / object di nomi di stili CSS in valori CSS

Per un esempio forzato, supponiamo che l’utente possa digitare un nome di colore in una texbox per il colore di sfondo (un selettore di colors jQuery sarebbe molto più bello):

 
...

Fiddle per entrambi i precedenti.

Il violino contiene anche un esempio di ng-show e ng-hide . Se una casella è selezionata, oltre al colore di sfondo che diventa rosa, viene mostrato del testo. Se “rosso” è inserito nella casella di testo, un div diventa nascosto.

Ho riscontrato problemi durante l’applicazione di classi all’interno di elementi di tabella quando una class era già applicata all’intera tabella (ad esempio, un colore applicato alle righe dispari ). Sembra che quando si ispeziona l’elemento con gli Strumenti per sviluppatori , lo stile element.style non abbia uno stile assegnato. Quindi, invece di usare ng-class , ho provato ad usare ng-style , e in questo caso, il nuovo attributo CSS appare all’interno di element.style . Questo codice funziona alla grande per me:

  [...amazing code...] {{ myvar }} [...more amazing code...]  

Myvar è ciò che sto valutando, e in ogni caso applico uno stile a ogni

seconda del valore myvar , che sovrascrive lo stile corrente applicato dalla class CSS per l’intera tabella.

AGGIORNARE

Se si desidera applicare una class alla tabella, ad esempio, quando si visita una pagina o in altri casi, è ansible utilizzare questa struttura:

 
  • Fondamentalmente, ciò di cui abbiamo bisogno per triggersre una class ng è la class da applicare e una dichiarazione vera o falsa. True applica la class e false no. Quindi qui abbiamo due controlli del percorso della pagina e un OR tra di loro, quindi se siamo in /route_a O siamo in route_b , verrà applicata la class triggers .

    Funziona solo con una funzione logica a destra che restituisce vero o falso.

    Quindi nel primo esempio, ng-style è condizionato da tre affermazioni. Se tutti sono falsi, non viene applicato alcuno stile, ma seguendo la nostra logica, almeno uno verrà applicato, quindi, l’espressione logica verificherà quale confronto di variabili è vero e poiché un array non vuoto è sempre true, che sarà lasciato un array come return e con un solo true, considerando che stiamo usando OR per l’intera risposta, lo stile rimanente verrà applicato.

    A proposito, ho dimenticato di darti la funzione isActive ():

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

    NUOVO AGGIORNAMENTO

    Qui hai qualcosa che trovo davvero utile. Quando è necessario applicare una class in base al valore di una variabile, ad esempio un’icona a seconda del contenuto del div , è ansible utilizzare il seguente codice (molto utile in ng-repeat ):

      

    Icone da Font Awesome

    Funziona bene quando non è ansible utilizzare ng-class (ad esempio quando si disegna SVG):

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

    (Penso che tu debba essere sull’ultimo angular instabile per usare ng-attr-, al momento sono su 1.1.4)

    Ho pubblicato un articolo su come lavorare con AngularJS + SVG. Parla di questo problema e di numerosi altri. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

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

    e codice

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

    Questa soluzione ha fatto il trucco per me

     ... 

    Un’altra opzione quando hai bisogno di un semplice stile css di una o due proprietà:

    Vista:

      [...amazing code...]  {{ element.myvar }}  [...more amazing code...]  

    controller:

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

    Vedi il seguente esempio

        Demo Changing CSS Classes Conditionally with Angular      Teams 

    Puoi usare l’espressione ternaria. Ci sono due modi per farlo:

    o…

    A partire da AngularJS v1.2.0rc, ng-class e anche ng-attr-class falliscono con gli elementi SVG (Hanno funzionato prima, anche con il binding normale all’interno dell’attributo class)

    In particolare, nessuno di questi lavori ora:

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

    Come soluzione, devo usare

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

    e poi usare lo stile

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

    Un altro modo (in futuro) per applicare in modo condizionale lo stile è creando in modo condizionale uno stile con ambito

      

    Ma al giorno d’oggi solo FireFox supporta gli stili con ambito.

    bene vorrei suggerire di controllare le condizioni nel controller con una funzione che restituisce true o false .

     
    {{day.date}}

    e nel controller controllare la condizione

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

    C’è un’altra opzione che ho scoperto di recente che alcune persone potrebbero trovare utile perché ti permette di cambiare una regola CSS all’interno di un elemento di stile – evitando così la necessità di un uso ripetuto di una direttiva angular come ng-style, ng-class, ng-show, ng-hide, ng-animate e altri.

    Questa opzione utilizza un servizio con variabili di servizio impostate da un controller e controllate da una direttiva attributo che chiamo “custom-style”. Questa strategia potrebbe essere utilizzata in molti modi diversi e ho cercato di fornire una guida generale con questo violino .

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

    Una cosa da guardare è che se lo stile CSS ha dei trattini, devi rimuoverli. Quindi se vuoi impostare il background-color , il modo corretto è:

     ng-style="{backgroundColor:myColor}"