¿Cómo aplico condicionalmente estilos CSS en AngularJS?

Resuelto Mark Rajcok asked hace 12 años • 14 respuestas

P1. Supongamos que quiero alterar el aspecto de cada "elemento" que un usuario marca para eliminar antes de presionar el botón principal "eliminar". (Esta respuesta visual inmediata debería eliminar la necesidad del proverbial cuadro de diálogo "¿está seguro?"). El usuario marcará las casillas de verificación para indicar qué elementos deben eliminarse. Si una casilla de verificación no está marcada, ese elemento debería volver a su aspecto normal.

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

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

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

Mark Rajcok avatar Dec 11 '12 10:12 Mark Rajcok
Aceptado

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

  • ng-class : se usa cuando el conjunto de estilos CSS es estático/conocido de antemano
  • ng-style : utilícelo cuando no pueda definir una clase CSS porque los valores de estilo pueden cambiar dinámicamente. Piense en el control programable de los valores de estilo.
  • ng-show y ng-hide : utilícelos si solo necesita mostrar u ocultar algo (modifica CSS)
  • ng-if : nuevo en la versión 1.1.5, utilícelo en lugar del más detallado ng-switch si solo necesita verificar una única condición (modifica DOM)
  • ng-switch : use en lugar de usar varios ng-shows mutuamente excluyentes (modifica DOM)
  • ng-disabled y ng-readonly : se utilizan para restringir el comportamiento del elemento del formulario
  • ng-animate : nuevo en la versión 1.1.4, se usa para agregar transiciones/animaciones CSS3

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

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


El primer trimestre parece un buen caso para ng-class: el estilo CSS se puede capturar en una clase.

ng-class acepta una "expresión" que debe evaluarse como una de las siguientes:

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

Suponiendo que sus elementos se muestran usando ng-repeat sobre algún modelo de matriz, y que cuando la casilla de verificación de un elemento está marcada, desea aplicar la pending-deleteclase:

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

Arriba, utilizamos el tipo de expresión ng-class n.° 3: un mapa/objeto de nombres de clases a valores booleanos.


La segunda pregunta parece un buen caso para ng-style: el estilo CSS es dinámico, por lo que no podemos definir una clase para esto.

ng-style acepta una "expresión" que debe evaluarse como:

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

Para un ejemplo artificial, supongamos que el usuario puede escribir el nombre de un color en un cuadro de texto para el color de fondo (un selector de color jQuery sería mucho mejor):

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


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 casilla de verificación, además de que el color de fondo se vuelve rosa, se muestra algo de texto. Si se ingresa 'rojo' en el cuadro de texto, un div queda oculto.

Mark Rajcok avatar Dec 11 '2012 03:12 Mark Rajcok

He encontrado problemas al aplicar clases dentro de elementos de la tabla cuando ya tenía una clase aplicada a toda la tabla (por ejemplo, un color aplicado a las filas impares <myClass tbody tr:nth-child(even) td>). Parece que cuando inspeccionas el elemento con Developer Tools , element.styleno tiene ningún estilo asignado. Entonces, en lugar de usar ng-class, intenté usar ng-styley, en este caso, el nuevo atributo CSS aparece dentro element.style. Este código funciona muy bien para mí:

<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 es lo que estoy evaluando, y en cada caso aplico un estilo a cada uno <td>dependiendo del valor de myvar , que sobrescribe el estilo actual aplicado por la clase CSS para toda la tabla.

ACTUALIZAR

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

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

Básicamente, lo que necesitamos para activar una ng-class es la clase a aplicar y una declaración de verdadero o falso. True aplica la clase y false no. Entonces aquí tenemos dos comprobaciones de la ruta de la página y un OR entre ellas, por lo que si estamos en OR /route_a ,route_b se aplicará la clase activa .

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

Entonces, en el primer ejemplo, el estilo ng está condicionado por tres declaraciones. Si todas son falsas, no se aplica ningún estilo, pero siguiendo nuestra lógica, se aplicará al menos uno, por lo que la expresión lógica verificará qué variable de comparación es verdadera y como una matriz no vacía siempre es verdadera, eso Dejó una matriz como retorno y con solo uno verdadero, considerando que estamos usando OR para toda la respuesta, se aplicará el estilo restante.

Por cierto, se me 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 necesites aplicar una clase dependiendo del valor de una variable, por ejemplo, un icono dependiendo del contenido del div, puedes utilizar el siguiente código (muy útil en ng-repeat):

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

Iconos de Font Awesome

Timbergus avatar Sep 20 '2013 06:09 Timbergus