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.

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>

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>

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>

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>

2
Llegué a esta pregunta para el operador ternario, pero al final fui con un filtro y me sentí muy bien ... = D
— slacktracer



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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.