Clase de alternar AngularJS usando ng-class

217

Estoy tratando de alternar la clase de un elemento usando ng-class

<button class="btn">
  <i ng-class="{(isAutoScroll()) ? 'icon-autoscroll' : 'icon-autoscroll-disabled'}"></i>
</button>

isAutoScroll ():

$scope.isAutoScroll = function()
{
    $scope.autoScroll = ($scope.autoScroll) ? false : true;
    return $scope.autoScroll;
}

Básicamente, si $scope.autoScrolles cierto, quiero que sea ng-class icon-autoscrolly si es falso, quiero que seaicon-autoscroll-disabled

Lo que tengo ahora no funciona y produce este error en la consola

Error: Lexer Error: Unexpected next character at columns 18-18 [?] in expression [{(isAutoScroll()) ? 'icon-autoscroll' : 'icon-autoscroll-disabled'}].

¿Cómo hago esto correctamente?

EDITAR

solución 1: (anticuado)

<button class="btn" ng-click="autoScroll = !autoScroll">
  <i ng-class="{'icon-autoscroll': autoScroll, 'icon-autoscroll-disabled': !autoScroll}"></i>
</button>

EDITAR 2

solución 2:

Quería actualizar la solución ya que Solution 3, proporcionada por Stewie, debería ser la utilizada. Es el más estándar cuando se trata de operador ternario (y para mí, el más fácil de leer). La solución sería

<button class="btn" ng-click="autoScroll = !autoScroll">
  <i ng-class="autoScroll ? 'icon-autoscroll' : 'icon-autoscroll-disabled'"></i>
</button>

se traduce en:

if (autoScroll == true) ?// use class 'icon-autoscroll' :// else use'icon-autoscroll-disabled'

Ronnie
fuente
no puede usar condicionales en angular expressionspor documentos => No hay declaraciones de flujo de control: no puede hacer nada de lo siguiente en expresión angular: condicionales, bucles o tirar. Use otra función o directiva
charlietfl
@Ronnie Vi tu solución, y fue genial. pero me pregunto por qué el autoScrollefecto aquí solo tendrá efecto en cada botón. (Probé esto con varios botones, y también funciona bien) Quiero decir, cuando hago clic en cada botón, afecta solo ese botón, en lugar de todos los botones.
zx1986

Respuestas:

436

Cómo usar condicional en ng-class:

Solución 1:

<i ng-class="{'icon-autoscroll': autoScroll, 'icon-autoscroll-disabled': !autoScroll}"></i>

Solución 2:

<i ng-class="{true: 'icon-autoscroll', false: 'icon-autoscroll-disabled'}[autoScroll]"></i>

Solución 3 (angular v.1.1.4 + soporte introducido para operador ternario):

<i ng-class="autoScroll ? 'icon-autoscroll' : 'icon-autoscroll-disabled'"></i>

Saqueador

Stewie
fuente
3
El segundo ejemplo es más limpio, pero es ridículo que no puedas poner la variable que estás evaluando al frente de la expresión ... simplemente se lee divertido. Imagina mirar la expresión como una declaración if: "if (variable) verdadero: haz esto, falso: haz eso ... ugh #fullynerdy
mattdlockyer
10
@Stewie Faaakin hermosa pareja, me encanta cómo se ve como un código real y no un marcado de expresión
bastarda
En realidad, evaluar el valor primero es bastante útil ya que evita asignar accidentalmente a la variable un nuevo valor.
lharby
Ternary es exactamente lo que estaba buscando. Buen trabajo proporcionando tres ejemplos con los detalles de soporte de la versión.
TaeKwonJoe
13

Como solución alternativa, basada en el operador lógico javascript '&&' que devuelve la última evaluación, también puede hacerlo así:

<i ng-class="autoScroll && 'icon-autoscroll' || !autoScroll && 'icon-autoscroll-disabled'"></i>

Es solo una sintaxis un poco más corta, pero para mí es más fácil de leer.

Lukus
fuente
10

Agregue más de una clase según la condición:

<div ng-click="AbrirPopUp(s)" 
ng-class="{'class1 class2 class3':!isNew, 
           'class1 class4': isNew}">{{ isNew }}</div>

Aplicar: class1 + class2 + class3 cuando isNew = false ,

Aplicar: class1 + class4 cuando isNew = true

RolandoCC
fuente
6
<div data-ng-init="featureClass=false" 
     data-ng-click="featureClass=!featureClass" 
     data-ng-class="{'active': featureClass}">
    Click me to toggle my class!
</div>

De manera análoga al toggleClassmétodo de jQuery , esta es una forma de activar active/ desactivar la clase cuando se hace clic en el elemento.

Pavel Levin
fuente
2
¿Podría proporcionar más información sobre su respuesta en inglés? ¿Cómo es diferente de las respuestas que ya están aquí?
Onots
2
No estoy seguro de por qué esta respuesta tiene tantos votos negativos. Esta es la solución que realmente funcionó mejor para mí que los otros anteriores ...
Paulo Griiettner
2
Creo que la descripción está mal escrita y la gente reacciona a la palabra "jQuery". Lo que la descripción debe decir es "Esto es análogo a la función toggleClass en JQuery". Por cierto, ¿necesitas iniciar la variable?
Diseño de Adrian
1

el desplazamiento automático se definirá y modificará en el controlador.

<span ng-class= "autoscroll?'class_if_true':'class_if_false'"></span>

Agregue varias clases según la condición por:

<span ng-class= "autoscroll?'first second third':'classes_if_false'"></span>

Harshit Pant
fuente
-1

Hice este trabajo de esta manera:

<button class="btn" ng-click='toggleClass($event)'>button one</button>
<button class="btn" ng-click='toggleClass($event)' >button two</button>

// en tu controlador

 $scope.toggleClass = function (event){
        $(event.target).toggleClass('active');
    }
Ruhul Amin
fuente
2
Si bien eso funciona, estás mezclando angular y jQuery. Deberías intentar evitarlo si puedes. Lo que se solicitó originalmente se puede hacer sin un evento de clic. ¿Qué sucede si tiene otro botón que se supone que alterna esta clase en su botón de arriba? No se actualizará ahora porque lo está cambiando al hacer clic y no a través de ng-class
Ronnie
1
Es de jqLite. Para más docs.angularjs.org/api/ng/function/angular.element
Ruhul Amin
1
Entiendo. Mi punto es que no necesita usar jQuery para lograr la respuesta a la pregunta original.
Ronnie