Question sinon else dans les templates AngularJS


Je veux faire une condition dans un template AngularJS. Je vais chercher une liste de vidéos de l'API Youtube. Certaines vidéos sont en format 16: 9 et d'autres en format 4: 3.

Je veux faire une condition comme celle-ci:

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

Je répète les vidéos en utilisant 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 un gabarit?

645
2018-04-04 11:50


origine


Réponses:


Angularjs (versions inférieures à 1.1.5) ne fournit pas if/else fonctionnalité. Voici quelques options à considérer pour ce que vous voulez réaliser:

(Aller à la mise à jour ci-dessous (# 5) si vous utilisez la version 1.1.5 ou supérieure)

1. Opérateur ternaire:

Comme suggéré par @Kirk dans les commentaires, le moyen le plus propre de le faire serait d'utiliser un opérateur ternaire comme suit:

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

2. ng-switch directif:

peut être utilisé quelque chose comme le suivant.

<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

Alternativement, vous pouvez également utiliser ng-show/ng-hide mais en utilisant cela, cela rendra à la fois une grande vidéo et un petit élément vidéo, puis cacher celui qui répond à la ng-hide condition et montre 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 ng-class directif.

Cela peut être utilisé comme suit.

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

Ce qui précède va essentiellement ajouter un large-video classe css à l'élément div si video.large est vrai.

METTRE À JOUR: Angulaire 1.1.5 introduit le ngIf directive

5 ng-if directif:

Dans les versions ci-dessus 1.1.5 vous pouvez utiliser le ng-if directif. Cela supprimerait 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>

1193
2018-04-04 11:58



Dans la dernière version d'Angular (à partir de 1.1.5), ils ont inclus une directive conditionnelle appelée ngIf. C'est différent de ngShow et ngHide en ce que les éléments ne sont pas cachés, mais ne sont 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>

164
2017-07-09 16:54



Le ternaire est la manière la plus claire de le faire.

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

133
2017-09-05 05:18



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

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

Dans ses propres mots, c'est juste "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>

41
2017-10-03 21:38



Vous pouvez utiliser votre video.yt$aspectRatio directement au travers d'un filtre et en associant 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>

26
2018-04-04 16:45



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

Je voudrais définir une fonction dans le contrôleur qui calcule les valeurs de pixels.

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
2017-10-29 11:35



Je suis d'accord qu'un ternaire est extrêmement propre. On dirait que c'est très situationnel mais comme quelque chose j'ai besoin d'afficher div ou p ou table, donc avec un tableau je ne préfère 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
2017-07-23 20:58



    <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
2017-12-08 12:36



Une possibilité pour Angular: J'ai dû inclure une instruction if dans la partie html, j'ai dû vérifier si toutes les variables d'une URL que je produis sont 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 template:

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

Et la partie dactylographiée:

  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


1
2017-10-09 08:44