web-dev-qa-db-fra.com

déclaration if else dans les modèles AngularJS

Je souhaite créer une condition dans un modèle AngularJS. Je récupère une liste de vidéos de l'API Youtube. Certaines des vidéos sont au format 16: 9 et d'autres au format 4: 3.

Je veux faire une condition comme ceci:

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

J'itère les vidéos avec ng-repeat. Je n'ai aucune idée de ce que je devrais faire pour cette condition:

  • Ajouter une fonction dans la portée?
  • Faites-le dans le modèle?
684
vzhen

Angularjs (versions inférieures à 1.1.5) ne fournit pas la fonctionnalité _if/else_. Voici quelques options à considérer pour ce que vous voulez atteindre:

( Passez à la mise à jour ci-dessous (# 5) si vous utilisez la version 1.1.5 ou une version ultérieure )

1. Opérateur ternaire:

Comme suggéré par @Kirk dans les commentaires, la manière la plus propre de procéder consiste à utiliser un opérateur ternaire comme suit:

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

2. ng-switch directive:

peut être utilisé quelque chose comme ce qui suit.

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

Sinon, vous pouvez aussi utiliser _ng-show/ng-hide_ mais utiliser ceci rendra à la fois une grande vidéo et un petit élément vidéo, puis cachera celui qui remplit la condition _ng-hide_ et affiche celui qui répond à _ng-show_ condition. Donc, sur chaque page, vous allez réellement rendre deux éléments différents.

4. Une autre option à considérer est la directive ng-class .

Ceci peut être utilisé comme suit.

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

Ce qui précède va fondamentalement ajouter une classe _large-video_ css à l'élément div si _video.large_ est véridique.

UPDATE: Angular 1.1.5 introduit le ngIf directive

5. ng-if directive:

Dans les versions ci-dessus _1.1.5_, vous pouvez utiliser la directive _ng-if_. Cela supprime l'élément si l'expression fournie renvoie false et réinsère le element dans le DOM si l'expression renvoie true. Peut être utilisé comme suit.

_<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>
_
1259
Amyth

Dans la dernière version de Angular (version 1.1.5), ils ont inclus une directive conditionnelle appelée ngIf. Il diffère de ngShow et ngHide en ce que les éléments ne sont pas cachés, mais pas inclus dans le DOM. Ils sont très utiles pour les composants coûteux à créer mais non utilisés:

<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>
172
Brian Genisio

Ternary est le moyen le plus clair de le faire.

<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
136
Oliver Dixon

Angular lui-même ne fournit pas de fonctionnalité if/else, mais vous pouvez l'obtenir en incluant ce module:

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

Selon ses propres termes, il s’agit simplement d’une "simple collection de directives de flux de contrôle: ng-if, ng-else-if et ng-else". C'est facile et intuitif à utiliser.

Exemple:

<div ng-if="someCondition">
    ...
</div>
<div ng-else-if="someOtherCondition">
    ...
</div>
<div ng-else>
    ...
</div>
42
lpappone

Vous pouvez utiliser votre propriété video.yt$aspectRatio directement en la passant à travers un filtre et en liant le résultat à l'attribut height de votre modèle.

Votre filtre ressemblerait à quelque chose comme:

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

Et le modèle serait:

<video height={{video.yt$aspectRatio | videoHeight}}></video>
27
Noah Freitas

Dans ce cas, vous souhaitez "calculer" une valeur de pixel en fonction d'une propriété d'objet.

Je définirais une fonction dans le contrôleur qui calcule les valeurs de pixel.

Dans le contrôleur:


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

Ensuite, dans votre modèle, vous écrivez simplement:


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

10
Spock

Je conviens qu'un ternaire est extrêmement propre. Il semble que la situation soit très situationnelle, mais que je dois afficher div, p ou tableau, je ne préfère donc pas un ternaire pour des raisons évidentes. Faire un appel à une fonction est généralement idéal ou dans mon cas, je l’ai fait:

<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
Tom Stickel
    <div ng-if="modeldate==''"><span ng-message="required" class="change">Date is required</span> </div>

vous pouvez utiliser la directive ng-if comme ci-dessus.

3
JBhardwaj

Une possibilité pour Angular: je devais inclure une instruction if dans la partie html, je devais vérifier si toutes les variables d’une URL que je produisais étaient définies. Je l'ai fait de la manière suivante et cela semble être une approche flexible. J'espère que ce sera utile pour quelqu'un.

La partie html dans le modèle:

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

Et la partie TypeScript:

  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';
      }
  }

Merci et meilleures salutations,

Jan