If else statement in AngularJS templates

Quero fazer uma condição num modelo AngularJS. Vou buscar uma lista de vídeo à API do Youtube. Alguns dos vídeos estão na proporção 16: 9 e alguns estão na proporção 4:3.

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 a iterar os vídeos usando ng-repeat. Não faço ideia do que devo fazer para esta condição:

  • Adicionar uma função no âmbito?
  • fá-lo no modelo?
Author: dpassage, 2013-04-04

9 answers

Angularjs (versões abaixo de 1.1.5) não fornece a funcionalidade if/else. A seguir estão algumas opções a considerar para o que você quer alcançar:

(Saltar para a actualização abaixo (#5) Se estiver a usar a versão 1.1.5 ou maior)

1. Operador ternário:

Como sugerido por @Kirk nos comentários, a maneira mais limpa de fazer isto seria usar um operador ternário do seguinte modo:

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

2. ng-switch directiva:

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

Em alternativa, poderá também usar {[[8]} mas se usar isto irá representar tanto um vídeo grande como um pequeno elemento de vídeo e, em seguida, esconder o que cumpre a condição ng-hide e mostra o que cumpre a condição ng-show. Então em cada página você estará realmente rendendo dois elementos diferentes.

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

Isto pode ser usado como se segue.

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

O acima, basicamente, irá adicionar uma classe large-video css ao elemento div se video.large for truthy.

Actualização: Angular 1.1.5 introduziu o ngIf directive

5. ng-if directiva:

Nas versões acima 1.1.5 pode utilizar a Directiva ng-if. Isto removeria o elemento se a expressão fornecida devolvesse false e re-inserisse o element no DOM se a expressão devolve true. Pode ser usado como segue.

<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>
 1201
Author: Amyth, 2018-08-26 06:22:21

Na última versão do Angular (a partir de 1.1.5), eles incluíram uma directiva condicional chamada ngIf. É diferente de ngShow e ngHide em que os elementos não estão escondidos, mas não estão incluídos no DOM. Eles são muito úteis para componentes que são caros para 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>
 166
Author: Brian Genisio, 2013-09-17 19:15:17
Ternary é a maneira mais clara de fazer isto.
<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
 133
Author: Oliver Dixon, 2014-09-05 05:18:07

O Angular em si não fornece a funcionalidade "se/else", mas você pode obtê-la incluindo este módulo:

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

Em suas próprias palavras, é apenas " uma simples coleção de diretivas 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>
 41
Author: lpappone, 2016-06-06 07:25:32

Pode usar a sua propriedade video.yt$aspectRatio directamente passando-a através de um filtro e ligando o resultado ao atributo altura do seu modelo.

O seu filtro pareceria 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>
 26
Author: Noah Freitas, 2013-04-04 16:45:03

Neste caso, deseja "calcular" um valor de pixel, dependendo de uma propriedade do objecto.

Eu definiria uma função no controlador que calcula os valores dos pixels.

No controlador:


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

Então no seu modelo você apenas escreve:


element height="{{ GetHeight(aspect) }}px "

 10
Author: Spock, 2013-10-29 11:47:13
Concordo que um ternário é extremamente limpo. Parece que é muito situacional embora como algumas coisas que eu preciso mostrar div ou P ou mesa, assim com uma tabela eu não prefiro um ternário por razões óbvias. Fazer uma chamada para uma função é tipicamente ideal ou no meu caso eu fiz isso:
<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>
 8
Author: Tom Stickel, 2015-07-23 20:58:50
    <div ng-if="modeldate==''"><span ng-message="required" class="change">Date is required</span> </div>

Pode utilizar a Directiva ng-se a Directiva acima referida.

 3
Author: JBhardwaj, 2016-12-08 12:36:51

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

A parte html do modelo:

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

E a parte do texto:

  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

 1
Author: Jan Clemens Stoffregen, 2017-10-09 09:25:45