Instrução if else nos modelos AngularJS

702

Eu quero fazer uma condição em um modelo AngularJS. Busco uma lista de vídeos da API do YouTube. Alguns vídeos estão na proporção 16: 9 e outros na proporção 4: 3.

Eu quero fazer uma condição como esta:

if video.yt$aspectRatio equals widescreen then 
    element's attr height="270px"
else
    element's attr height="360px"

Estou repetindo os vídeos usando ng-repeat. Não tenho idéia do que devo fazer para esta condição:

  • Adicionar uma função no escopo?
  • Faça isso no modelo?
vzhen
fonte
2
Encontrei um ng-if artigos aqui. goo.gl/wQ30uf
virender

Respostas:

1284

O Angularjs (versões abaixo da 1.1.5) não fornece a if/elsefuncionalidade. A seguir, algumas opções a serem consideradas para o que você deseja alcançar:

( Salte para a atualização abaixo (# 5) se você estiver usando a versão 1.1.5 ou superior )

1. Operador ternário:

Conforme sugerido por @Kirk nos comentários, a maneira mais limpa de fazer isso seria usar um operador ternário da seguinte maneira:

<span>{{isLarge ? 'video.large' : 'video.small'}}</span>

2. ng-switchdirectiva:

pode ser usado algo como o seguinte.

<div ng-switch on="video">
    <div ng-switch-when="video.large">
        <!-- code to render a large video block-->
    </div>
    <div ng-switch-default>
        <!-- code to render the regular video block -->
    </div>
</div>

3. ng-hide/ ng-showdiretivas

Como alternativa, você também pode usar, ng-show/ng-hidemas usá-lo na verdade renderiza um vídeo grande e um pequeno elemento de vídeo e depois oculta o que atende à ng-hidecondição e mostra o que atendeng-show condição. Então, em cada página, você estará renderizando dois elementos diferentes.

4. Outra opção a considerar é a ng-classdiretiva.

Isso pode ser usado da seguinte maneira.

<div ng-class="{large-video: video.large}">
    <!-- video block goes here -->
</div>

O exemplo acima basicamente adicionará uma large-videoclasse css ao elemento div, se video.largefor verdade.

UPDATE: Angular 1.1.5 introduziu ongIf directive

5. ng-ifdirectiva:

Nas versões acima, 1.1.5você pode usar a ng-ifdiretiva. Isso removeria o elemento se a expressão fornecida retornar falsee reinserir o elementno DOM se a expressão retornar true. Pode ser usado da seguinte maneira.

<div ng-if="video == video.large">
    <!-- code to render a large video block-->
</div>
<div ng-if="video != video.large">
    <!-- code to render the regular video block -->
</div>
Um mito
fonte
9
Deve ser ng-switch on="video"em vezng-switch-on="video"
czerasz
4
Como é que isso? if () {} else if () {} else if () {} else {} Mas inclua no dom apenas um elemento
falko
208
Também ternário<span>{{isAdded ? 'Added' : 'Add to cart'}}</span>
Kirk Strobeck
16
Lembre-se de que ng-ifNÃO incluirá os elementos incluídos no DOM até que sua condição seja avaliada como true, ao contrário de ng-hidee ng-show.
Wilhelm Murdoch
1
Por que não simplesmente ng-switch="video"? Algum problema? ou não estava disponível anteriormente? Para mim, isso está funcionando muito bem
Sami
175

Na versão mais recente do Angular (a partir do 1.1.5), eles incluíram uma diretiva condicional chamada ngIf. É diferente ngShowe ngHideporque os elementos não estão ocultos, mas não estão incluídos no DOM. Eles são muito úteis para componentes que são caros de criar, mas não são usados:

<div ng-if="video == video.large">
    <!-- code to render a large video block-->
</div>
<div ng-if="video != video.large">
    <!-- code to render the regular video block -->
</div>
Brian Genisio
fonte
5
Lembre-se de que ng-ifapresenta um escopo isolado , para que ele $parentse torne $parent.$parentno corpo de ng-if.
David Salamon
142

Ternário é a maneira mais clara de fazer isso.

<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
Oliver Dixon
fonte
Ho para fazer isso com 2 condição em ou? como <div> {{A == B || A == C? 'varIsTrue': 'varIsFalse'}} </div>
Jun
2
Embrulhe-o (A == B || A == C)
Oliver Dixon
1
amo esta resposta! Usando directivas ñg- dá muita html espaços em branco se um div não satisfaz a condição ..
sksallaj
48

O próprio Angular não fornece a funcionalidade if / else, mas você pode obtê-lo incluindo este módulo:

https://github.com/zachsnow/ng-elif

Em suas próprias palavras, é apenas "uma coleção simples de diretrizes de fluxo de controle: ng-if, ng-else-if e ng-else". É fácil e intuitivo de usar.

Exemplo:

<div ng-if="someCondition">
    ...
</div>
<div ng-else-if="someOtherCondition">
    ...
</div>
<div ng-else>
    ...
</div>
lpappone
fonte
1
Eu não quero repetir o código em div novamente e novamente.
1
Você não precisa repetir nada - você poderia facilmente fazer ng-if="someCondition && someOtherCondition". Talvez eu entenda mal? (Eu escrevi esse módulo - ele deve funcionar apenas como ife elseem JS).
Zach Snow
1
Este é um salva-vidas absoluto. Isso deve fazer parte do núcleo Angular, é indispensável na codificação do modelo. Muito mais limpo do que ter operadores ternários em todo o lugar e supera as limitações do ng-switch não poder avaliar expressões.
Nico Westerdale
Obrigado @NicoWesterdale! Além disso, eu adicionei uma versão mais rica do switch de ng que você pode achar útil: github.com/zachsnow/ng-cases
Zach Snow
30

Você pode usar sua video.yt$aspectRatiopropriedade diretamente passando-a por um filtro e vinculando o resultado ao atributo height no seu modelo.

Seu filtro seria algo como:

app.filter('videoHeight', function () {
  return function (input) {
    if (input === 'widescreen') {
      return '270px';
    } else {
      return '360px';
    }
  };
});

E o modelo seria:

<video height={{video.yt$aspectRatio | videoHeight}}></video>
Noah Freitas
fonte
E o seu código quando video.yt$aspectRatioestá vazio ou indefinido? É possível aplicar um valor padrão?
Fractaliste 31/03
13

Nesse caso, você deseja "calcular" um valor de pixel, dependendo da propriedade de um objeto.

Eu definiria uma função no controlador que calcula os valores de pixel.

No controlador:


$scope.GetHeight = function(aspect) {
   if(bla bla bla) return 270;
   return 360;
}

Então, no seu modelo, você acabou de escrever:


element height="{{ GetHeight(aspect) }}px "
Spock
fonte
11

Concordo que um ternário é extremamente limpo. Parece que é muito situacional, mas, como algumas coisas, eu preciso exibir div ou p ou tabela; portanto, com uma tabela, não prefiro um ternário por razões óbvias. Fazer uma chamada para uma função é normalmente ideal ou, no meu caso, fiz o seguinte:

<div ng-controller="TopNavCtrl">
        <div ng-if="info.host ==='servername'">
            <table class="table">
                <tr ng-repeat="(group, status) in user.groups">
                    <th style="width: 250px">{{ group }}</th>
                    <td><input type="checkbox" ng-model="user.groups[group]" /></td>
                </tr>
            </table>
        </div>
       <div ng-if="info.host ==='otherservername'">
            <table class="table">
                <tr ng-repeat="(group, status) in user.groups">
                    <th style="width: 250px">{{ group }}</th>
                    <td><input type="checkbox" ng-model="user.groups[group]" /></td>
                </tr>
            </table>
        </div>
</div>
Tom Stickel
fonte
4
    <div ng-if="modeldate==''"><span ng-message="required" class="change">Date is required</span> </div>

você pode usar a diretiva ng-if como acima.

JBhardwaj
fonte
3

Uma possibilidade para o Angular: eu tive que incluir uma instrução if na parte html, tive que verificar se todas as variáveis ​​de uma URL que produzi estão definidas. Fiz da seguinte maneira e parece ser uma abordagem flexível. Espero que seja útil para alguém.

A parte html no modelo:

    <div  *ngFor="let p of poemsInGrid; let i = index" >
        <a [routerLink]="produceFassungsLink(p[0],p[3])" routerLinkActive="active">
    </div>

E a parte datilografada:

  produceFassungsLink(titel: string, iri: string) {
      if(titel !== undefined && iri !== undefined) {
         return titel.split('/')[0] + '---' + iri.split('raeber/')[1];
      } else {
         return 'Linkinformation has not arrived yet';
      }
  }

Obrigado e cumprimentos,

Jan

Jan Clemens Stoffregen
fonte
2
Parece mais Angular que AngularJS.
pzaenger
@ pzaenger, sim, mas muitas respostas para essa pergunta funcionam para ambos, então acho que algumas pessoas, como eu, olham as respostas de qualquer maneira. Por favor, deixe-me saber se você se importa.
Jan Clemens Stoffregen
2
Bem. Pelo menos você deve mencionar isso em sua resposta.
pzaenger
@ pzaenger, obrigado por esta dica, mencionei agora.
Jan Clemens Stoffregen
1

ng If else

ng-if="receiptData.cart == undefined ? close(): '' ;"
Aamir Anwar
fonte