Operador ternario en plantillas AngularJS

239

¿Cómo se hace un ternario con AngularJS (en las plantillas)?

Sería bueno usar algunos atributos html (clases y estilo) en lugar de crear y llamar a una función del controlador.

cricardol
fuente

Respuestas:

374

Actualización : Angular 1.1.5 agregó un operador ternario , por lo que ahora podemos simplemente escribir

<li ng-class="$first ? 'firstRow' : 'nonFirstRow'">

Si está utilizando una versión anterior de Angular, sus dos opciones son:

  1. (condition && result_if_true || !condition && result_if_false)
  2. {true: 'result_if_true', false: 'result_if_false'}[condition]

El elemento 2. anterior crea un objeto con dos propiedades. La sintaxis de la matriz se utiliza para seleccionar la propiedad con nombre verdadero o la propiedad con nombre falso y devolver el valor asociado.

P.ej,

<li class="{{{true: 'myClass1 myClass2', false: ''}[$first]}}">...</li>
 or
<li ng-class="{true: 'myClass1 myClass2', false: ''}[$first]">...</li>

$ first se establece en verdadero dentro de una repetición ng para el primer elemento, por lo que lo anterior aplicaría las clases 'myClass1' y 'myClass2' solo la primera vez a través del ciclo.

Sin embargo, con ng-class hay una manera más fácil: ng-class toma una expresión que debe evaluarse en 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.

Un ejemplo de 1) se dio anteriormente. Aquí hay un ejemplo de 3, que creo que se lee mucho mejor:

 <li ng-class="{myClass: $first, anotherClass: $index == 2}">...</li>

La primera vez a través de un ciclo ng-repeat, se agrega la clase myClass. La 3ª vez ($ index comienza en 0), se agrega la clase anotherClass.

ng-style toma una expresión que debe evaluar a un mapa / objeto de nombres de estilo CSS a valores CSS. P.ej,

 <li ng-style="{true: {color: 'red'}, false: {}}[$first]">...</li>
Mark Rajcok
fuente
66
¡Si pudiera te votaría nuevamente por actualizar la pregunta!
Narretz
2
Yo me encargaré, @Narretz.
Ian Hunter
1
En el ejemplo de acceso a la clave de objeto, puede omitir la clave 'falsa' ya que de todos modos es una cadena vacía.
0xc0de
Palabra de advertencia, 1.1.5 no es estable actualmente.
Adam Grant
¿Qué sucede si el condicional cambia cuando se actualiza su modelo? Me gustaría ng-styleactualizar, pero parece que solo se evalúa cuando el elemento se procesa por primera vez. (Novato angular aquí)
Hartley Brody
86

Actualización: Angular 1.1.5 agregó un operador ternario, esta respuesta es correcta solo para las versiones anteriores a 1.1.5. Para 1.1.5 y posterior, vea la respuesta actualmente aceptada.

Antes de Angular 1.1.5:

La forma de un ternario en angularjs es:

((condition) && (answer if true) || (answer if false))

Un ejemplo sería:

<ul class="nav">
    <li>
        <a   href="#/page1" style="{{$location.path()=='/page2' && 'color:#fff;' || 'color:#000;'}}">Goals</a>
    </li>
    <li>
        <a   href="#/page2" style="{{$location.path()=='/page2' && 'color:#fff;' || 'color:#000;'}}">Groups</a>
    </li>
</ul>

o:

 <li  ng-disabled="currentPage == 0" ng-click="currentPage=0"  class="{{(currentPage == 0) && 'disabled' || ''}}"><a> << </a></li>
cricardol
fuente
1
Extraño. Eso no es muy intuitivo. Me pregunto por qué se implementó de esta manera.
Ben Lesh
44
Ternary nunca se implementó, pero esto es solo usar los operadores binarios de la forma en que funcionan.
Andrew Joslin
18
@blesh, AngularJS promueve la capacidad de prueba. Las plantillas no deben contener ninguna lógica. Un operador ternario en una plantilla se debe refactorizar a una llamada de función al controlador, para una mejor capacidad de prueba.
Marcello Nuccio
1
@ arg20 debe usar la directiva ngClass (o ngClassEven y ngClassOdd). Luego ponga toda la lógica para elegir las clases css en el controlador. Esto es mucho más fácil de probar automáticamente.
Marcello Nuccio
1
@ arg20 Dije que lo pusiera en el controlador, no en el modelo. Esto no debería ser un problema. Sin embargo, la documentación dice: "El resultado de la evaluación puede ser una cadena que representa nombres de clase delimitados por espacios, una matriz o un mapa de nombres de clase a valores booleanos". Lo que significa que puede usar "{cssclass: someBoolCheck ()}" como expresión, es decir, coloca la clase css en la vista y la lógica en el controlador. Mira este jsFiddle para ver un ejemplo.
Marcello Nuccio
23

Para textos en plantilla angular ( userTypees propiedad de $ scope, como $ scope.userType):

<span>
  {{userType=='admin' ? 'Edit' : 'Show'}}
</span>
Ikrom
fuente
11

Por ahora todos descubrimos que la versión 1.1.5 viene con un ternario adecuado en la $parsefunción, así que solo use esta respuesta como ejemplo de filtros:

angular.module('myApp.filters', [])

  .filter('conditional', function() {
    return function(condition, ifTrue, ifFalse) {
      return condition ? ifTrue : ifFalse;
    };
  });

Y luego úsalo como

<i ng-class="checked | conditional:'icon-check':'icon-check-empty'"></i>
ene
fuente
2
Llegué a esta pregunta para el operador ternario, pero al final fui con un filtro y me sentí muy bien ... = D
slacktracer
10

Si bien puede usar la condition && if-true-part || if-false-partsintaxis en versiones anteriores de angular, el operador ternario habitual condition ? true-part : false-partestá disponible en Angular 1.1.5 y versiones posteriores .

Aleksander Blomskøld
fuente
0
  <body ng-app="app">
  <button type="button" ng-click="showme==true ? !showme :showme;message='Cancel Quiz'"  class="btn btn-default">{{showme==true ? 'Cancel Quiz': 'Take a Quiz'}}</button>
    <div ng-show="showme" class="panel panel-primary col-sm-4" style="margin-left:250px;">
      <div class="panel-heading">Take Quiz</div>
      <div class="form-group col-sm-8 form-inline" style="margin-top: 30px;margin-bottom: 30px;">

        <button type="button" class="btn btn-default">Start Quiz</button>
      </div>
    </div>
  </body>

Botón de alternar y cambiar el encabezado del botón y mostrar / ocultar el panel div. Ver el Plunkr

Zahid Rahman
fuente