¿Cómo aplico condicionalmente estilos CSS en AngularJS?

Q1. Supongamos que quiero alterar el aspecto de cada “elemento” que un usuario marca para borrar antes de presionar el botón principal “eliminar”. (Esta retroalimentación visual inmediata debería eliminar la necesidad del cuadro de diálogo proverbial “¿está seguro?”). El usuario marcará las casillas de verificación para indicar qué elementos se deben eliminar. Si una checkbox está desmarcada, ese elemento debería volver a su aspecto normal.

¿Cuál es la mejor manera de aplicar o eliminar el estilo CSS?

Q2. Supongamos que quiero permitir que cada usuario personalice cómo se presenta mi sitio. Por ejemplo, seleccione de un conjunto fijo de tamaños de fuente, permita colores de primer plano y fondo definibles por el usuario, etc.

¿Cuál es la mejor manera de aplicar el estilo de CSS que el usuario selecciona / ingresa?

Angular proporciona una serie de directivas integradas para manipular estilos de CSS de forma condicional / dinámica:

  • ng-class : se usa cuando el conjunto de estilos CSS es estático / conocido antes de tiempo
  • ng-style : se usa cuando no se puede definir una clase CSS porque los valores de estilo pueden cambiar dinámicamente. Piensa en el control progtwigble de los valores de estilo.
  • ng-show y ng-hide – use si solo necesita mostrar u ocultar algo (modifica CSS)
  • ng-if -new en la versión 1.1.5, use en vez del más nostálgico conmutador-ng si solo necesita verificar una sola condición (modifica DOM)
  • ng-switch – usar en lugar de usar varios ng-shows mutuamente excluyentes (modifica DOM)
  • ng-disabled y ng-readonly : se usa para restringir el comportamiento del elemento de formulario
  • ng-animate – nuevo en la versión 1.1.4, uso para agregar transiciones / animaciones de CSS3

La “forma angular” normal implica vincular una propiedad de modelo / scope a un elemento UI que aceptará la entrada / manipulación del usuario (es decir, usar ng-model) y luego asociará la propiedad del modelo a una de las directivas incorporadas mencionadas anteriormente.

Cuando el usuario cambia la interfaz de usuario, Angular actualizará automáticamente los elementos asociados en la página.


Q1 suena como un buen caso para ng-class: el estilo CSS se puede capturar en una clase.

ng-class acepta una “expresión” que debe evaluar a uno de los siguientes:

  1. una cadena de nombres de clase delimitados por espacios
  2. una matriz de nombres de clase
  3. un mapa / objeto de nombres de clase a valores booleanos

Suponiendo que sus elementos se muestran usando ng-repeat en algún modelo de matriz, y que cuando la checkbox de un elemento está marcada, desea aplicar la clase pending-delete :

 
... HTML to display the item ...

Arriba, utilizamos la expresión ng-clase tipo # 3 – un mapa / objeto de nombres de clase a valores booleanos.


Q2 suena como un buen caso para el estilo ng: el estilo de CSS es dynamic, por lo que no podemos definir una clase para esto.

ng-style acepta una “expresión” que debe evaluar a:

  1. un mapa / objeto de nombres de estilo CSS a valores CSS

Para un ejemplo artificial, supongamos que el usuario puede escribir un nombre de color en un texbox para el color de fondo (un selector de color jQuery sería mucho más agradable):

 
...

Violín para ambos de los anteriores.

El violín también contiene un ejemplo de ng-show y ng-hide . Si se marca una checkbox, además del color de fondo que se vuelve rosa, se muestra texto. Si se ingresa ‘rojo’ en el cuadro de texto, un div se oculta.

He encontrado problemas al aplicar clases dentro de elementos de tabla cuando ya tenía una clase aplicada a toda la tabla (por ejemplo, un color aplicado a las filas impares ). Parece que cuando inspecciona el elemento con Developer Tools , element.style no tiene ningún estilo asignado. Entonces, en lugar de usar ng-class , he intentado usar ng-style , y en este caso, el nuevo atributo CSS aparece dentro de element.style . Este código funciona muy bien para mí:

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

Myvar es lo que estoy evaluando, y en cada caso aplico un estilo a cada

dependiendo del valor myvar , que sobrescribe el estilo actual aplicado por la clase CSS para toda la tabla.

ACTUALIZAR

Si desea aplicar una clase a la tabla, por ejemplo, al visitar una página o en otros casos, puede utilizar esta estructura:

 
  • Básicamente, lo que necesitamos para activar una clase ng es la clase a aplicar y una statement verdadera o falsa. True aplica la clase y false no. Así que aquí tenemos dos controles de la ruta de la página y un OR entre ellos, por lo que si estamos en /route_a O estamos en route_b , se route_b la clase activa .

    Esto funciona simplemente teniendo una función lógica a la derecha que devuelve verdadero o falso.

    Entonces, en el primer ejemplo, ng-style está condicionado por tres enunciados. Si todos son falsos, no se aplica ningún estilo, pero siguiendo nuestra lógica, se aplicará al menos uno, por lo tanto, la expresión lógica comprobará qué comparación de variables es verdadera y porque una matriz no vacía siempre es verdadera, eso Dejamos una matriz como retorno y con solo una verdad, considerando que estamos usando O para toda la respuesta, se aplicará el estilo restante.

    Por cierto, olvidé darte la función isActive ():

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

    NUEVA ACTUALIZACIÓN

    Aquí tienes algo que encuentro realmente útil. Cuando necesite aplicar una clase en función del valor de una variable, por ejemplo, un ícono que depende del contenido del div , puede usar el siguiente código (muy útil en ng-repeat ):

      

    Iconos de Font Awesome

    Esto funciona bien cuando ng-class no se puede usar (por ejemplo, al diseñar SVG):

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

    (Creo que necesitas estar en el último Angular inestable para usar ng-attr-, actualmente estoy en 1.1.4)

    He publicado un artículo sobre cómo trabajar con AngularJS + SVG. Habla sobre este y muchos otros. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

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

    y código

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

    Esta solución hizo el truco para mí

     ... 

    Otra opción cuando necesitas un estilo de CSS simple de una o dos propiedades:

    Ver:

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

    Controlador:

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

    Mira el siguiente ejemplo

        Demo Changing CSS Classes Conditionally with Angular      Teams 

    Puedes usar expresión ternaria. Hay dos maneras de hacer esto:

    o…

    A partir de AngularJS v1.2.0rc, ng-class e incluso ng-attr-class fallan con elementos SVG (Funcionaron antes, incluso con el enlace normal dentro del atributo de clase)

    Específicamente, ninguno de estos funciona ahora:

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

    Como solución, tengo que usar

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

    y luego estilo usando

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

    Una forma más (en el futuro) de aplicar el estilo de forma condicional es mediante la creación condicional del estilo de ámbito

      

    Pero hoy en día, solo FireFox admite estilos de ámbito.

    Bueno, le sugiero que verifique la condición en su controlador con una función que devuelva verdadero o falso .

     
    {{day.date}}

    y en tu controlador verifica la condición

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

    Hay una opción más que descubrí recientemente que algunas personas pueden encontrar útil porque le permite cambiar una regla de CSS dentro de un elemento de estilo, evitando así la necesidad de un uso repetido de una directiva angular como ng-style, ng-class, ng-show, ng-hide, ng-animate y otros.

    Esta opción hace uso de un servicio con variables de servicio que son establecidas por un controlador y observadas por una directiva de atributos que llamo “estilo personalizado”. Esta estrategia se puede usar de muchas maneras diferentes, e intenté proporcionar una guía general con este violín .

     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 para ver es: si el estilo CSS tiene guiones, debes eliminarlos. Entonces, si desea establecer background-color , la forma correcta es:

     ng-style="{backgroundColor:myColor}"