instruction if else dans les modèles AngularJS
Je veux faire une condition dans un modèle AngularJS. Je récupère une liste de vidéos de L'API Youtube. Certaines vidéos sont en 16:9 ratio et certaines sont 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 en utilisant ng-repeat
. Je n'ai aucune idée de ce que je dois faire pour cette condition:
- ajouter une fonction dans la portée?
- le faire dans le modèle?
9 réponses
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:
(Saut à la mise à jour ci-dessous (#5) si vous utilisez la version 1.1.5 ou plus)
1. Opérateur ternaire:
Comme suggéré par @Kirk dans les commentaires, la façon la plus propre de le faire serait d'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
Alternativement, vous pouvez également utiliser ng-show/ng-hide
mais l'utilisation de ceci rendra à la fois une grande vidéo et un petit élément vidéo, puis masquera celui qui répond à la condition ng-hide
et montrera celui qui répond à la condition ng-show
. Donc, sur chaque page, vous rendrez en fait deux éléments différents.
4. Une autre option à considérer est ng-class
directive.
Ceci peut être utilisé comme suit.
<div ng-class="{large-video: video.large}">
<!-- video block goes here -->
</div>
Ce qui précède ajoutera essentiellement une classe large-video
CSS à l'élément div si video.large
est véridique.
Mise à JOUR: Angulaire 1.1.5 introduit l'ngIf directive
5. ng-if
directive:
Dans les versions ci-dessus 1.1.5
vous pouvez utiliser le ng-if
directive. 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>
Dans la dernière version D'Angular (à partir de 1.1.5), ils ont inclus une directive conditionnelle appelée ngIf
. Il est différent de ngShow
et ngHide
en ce que les éléments ne sont pas cachés, mais pas du tout inclus dans le DOM. Ils sont très utiles pour les composants qui sont coûteux à créer mais ne sont pas 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>
Ternaire est la façon la plus claire de le faire.
<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
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
, Dans ses propres mots, c'est juste "une simple collection de flux de contrôle directives: ng-si, ng-sinon-si, et ng-chose d'autre."Il est facile et intuitif à utiliser.
Exemple:
<div ng-if="someCondition">
...
</div>
<div ng-else-if="someOtherCondition">
...
</div>
<div ng-else>
...
</div>
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 dans 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>
Dans ce cas, vous voulez "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 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 "
Je suis d'accord qu'un ternaire est très propre. Il semble que c'est très situationnel mais comme quelque chose que j'ai besoin d'afficher div ou p ou table , donc avec une table 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>
<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.
Une possibilité pour angulaire: 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 du 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 cordialement,
Jan