Operador ternário em modelos AngularJS


239

Como você faz um ternário com o AngularJS (nos modelos)?

Seria bom usar alguns atributos em html (classes e estilo) em vez de criar e chamar uma função do controlador.

Respostas:


374

Atualização : Angular 1.1.5 adicionou um operador ternário , então agora podemos simplesmente escrever

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

Se você estiver usando uma versão anterior do Angular, suas duas opções são:

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

o item 2. acima cria um objeto com duas propriedades. A sintaxe da matriz é usada para selecionar a propriedade com o nome true ou a propriedade com o nome false e retornar o valor associado.

Por exemplo,

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

$ first é definido como true dentro de um ng-repeat para o primeiro elemento, portanto, o acima aplicaria as classes 'myClass1' e 'myClass2' apenas na primeira vez no loop.

Com ng de classe existe uma maneira mais fácil, porém: NG-classe assume uma expressão que deve ser avaliada como um dos seguintes:

  1. uma sequência de nomes de classe delimitados por espaço
  2. uma matriz de nomes de classe
  3. um mapa / objeto de nomes de classe para valores booleanos.

Um exemplo de 1) foi dado acima. Aqui está um exemplo de 3, que eu acho que lê muito melhor:

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

Na primeira vez em um loop ng-repeat, a classe myClass é adicionada. Na terceira vez ($ index começa em 0), a classe anotherClass é adicionada.

ng-style usa uma expressão que deve ser avaliada em um mapa / objeto de nomes de estilos CSS para valores CSS. Por exemplo,

 <li ng-style="{true: {color: 'red'}, false: {}}[$first]">...</li>

6
Se eu pudesse, eu votaria novamente em você por atualizar a pergunta!
Narretz 29/05

2
Eu cuido disso, @Narretz.
Ian Hunter

1
No exemplo de acesso à chave de objeto, você pode pular a chave 'false', pois ela é uma string vazia.
0xc0de 22/07/2013

A palavra de aviso 1.1.5 não está estável no momento.
Adam Grant

E se as condições condicionais mudarem quando seu modelo for atualizado? Gostaria ng-stylede atualizar, mas parece ser avaliado apenas quando o elemento é renderizado pela primeira vez. (Angular noob aqui)
Hartley Brody

86

Atualização: o Angular 1.1.5 adicionou um operador ternário, esta resposta está correta apenas nas versões anteriores ao 1.1.5. Para 1.1.5 e posterior, consulte a resposta atualmente aceita.

Antes do Angular 1.1.5:

A forma de um ternário em angularjs é:

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

Um exemplo seria:

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

ou:

 <li  ng-disabled="currentPage == 0" ng-click="currentPage=0"  class="{{(currentPage == 0) && 'disabled' || ''}}"><a> << </a></li>

1
Esquisito. Isso não é muito intuitivo. Eu me pergunto por que foi implementado dessa maneira.
precisa

4
O Ternary nunca foi implementado, mas isso é apenas usar os operadores binários da maneira que eles funcionam.
Andrew Joslin

18
@blesh, o AngularJS promove a testabilidade. Os modelos não devem conter nenhuma lógica. Um operador ternário em um modelo deve ser refatorado para uma chamada de função ao controlador, para melhor testabilidade.
Marcello Nuccio

1
@ arg20 você deve usar a diretiva ngClass (ou ngClassEven e ngClassOdd). Em seguida, coloque toda a lógica para escolher as classes css no controlador. É muito mais fácil testar automaticamente.
Marcello Nuccio

1
@ arg20 eu disse para colocá-lo no controlador, não no modelo. Isso não deve ser um problema. No entanto, a documentação diz: "O resultado da avaliação pode ser uma sequência que representa nomes de classes delimitados por espaço, uma matriz ou um mapa de nomes de classes para valores booleanos". Significando que você pode usar "{cssclass: someBoolCheck ()}" como uma expressão, ou seja, você coloca a classe css na visualização e a lógica no controlador. Veja este jsFiddle para um exemplo.
Marcello Nuccio

23

Para textos em modelo angular ( userTypeé propriedade de $ scope, como $ scope.userType):

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

11

Até agora, todos descobrimos que a versão 1.1.5 vem com um ternário adequado na $parsefunção, portanto, use esta resposta como um exemplo de filtro:

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

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

E então use-o como

<i ng-class="checked | conditional:'icon-check':'icon-check-empty'"></i>

2
Eu vim para esta pergunta para o operador ternário, mas no final eu fui com um filtro e foi muito bom ... = 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>

O botão alterna e altera o cabeçalho do botão e mostra / oculta o painel div. Veja o Plunkr

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.