declaración if else en plantillas AngularJS

702

Quiero hacer una condición en una plantilla AngularJS. Busco una lista de videos de la API de Youtube. Algunos de los videos tienen una relación de 16: 9 y algunos tienen una relación de 4: 3.

Quiero hacer una condición como esta:

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

Estoy iterando los videos usando ng-repeat. No tengo idea de qué debo hacer para esta condición:

  • Agregar una función en el alcance?
  • ¿Hacerlo en plantilla?
vzhen
fuente
2
Encontré uno ng-si artículos aquí. goo.gl/wQ30uf
virender

Respuestas:

1284

Angularjs (versiones inferiores a 1.1.5) no proporciona la if/elsefuncionalidad. Las siguientes son algunas opciones a considerar para lo que desea lograr:

( Vaya a la actualización a continuación (# 5) si está utilizando la versión 1.1.5 o superior )

1. Operador ternario:

Según lo sugerido por @Kirk en los comentarios, la forma más limpia de hacerlo sería utilizar un operador ternario de la siguiente manera:

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

2. ng-switchdirectiva:

se puede usar algo como lo siguiente.

<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-showdirectivas

Alternativamente, también puede usarlo, ng-show/ng-hidepero usarlo en realidad representará un video grande y un elemento de video pequeño y luego ocultará el que cumpla la ng-hidecondición y muestre el que cumpla la ng-showcondición. Entonces, en cada página, realmente representará dos elementos diferentes.

4. Otra opción a considerar es la ng-classdirectiva.

Esto se puede usar de la siguiente manera.

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

Lo anterior básicamente agregará una large-videoclase css al elemento div si video.largees verdadero.

ACTUALIZACIÓN: Angular 1.1.5 introdujo elngIf directive

5. ng-ifdirectiva:

En las versiones anteriores 1.1.5, puede usar la ng-ifdirectiva. Esto eliminaría el elemento si la expresión proporcionada regresa falsey se vuelve a insertar elementen el DOM si la expresión regresa true. Se puede usar de la siguiente manera.

<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>
Un mito
fuente
99
Debería ser ng-switch on="video"en su lugarng-switch-on="video"
czerasz
44
Como hacer eso if () {} else if () {} else if () {} else {} Pero incluye en dom solo un elemento
falko
208
También ternario<span>{{isAdded ? 'Added' : 'Add to cart'}}</span>
Kirk Strobeck el
16
Tenga en cuenta que ng-ifNO agregará los elementos encerrados al DOM hasta que su condición evalúe true, a diferencia de ng-hidey ng-show.
Wilhelm Murdoch
1
¿Por qué no simplemente ng-switch="video"? ¿Algún problema? o no estaba disponible antes? Para mí está funcionando bastante bien
Sami
175

En la última versión de Angular (a partir de 1.1.5), han incluido una directiva condicional llamada ngIf. Es diferente de ngShowy ngHideen que los elementos no están ocultos, pero no están incluidos en el DOM. Son muy útiles para componentes que son costosos de crear pero que no se usan:

<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
fuente
55
Tenga en cuenta que ng-ifintroduce un alcance aislado , por lo que se $parentconvierte $parent.$parenten el cuerpo de ng-if.
David Salamon
142

Ternary es la forma más clara de hacerlo.

<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
Oliver Dixon
fuente
Ho para hacer esto con 2 condiciones en o ?? como <div> {{A == B || A == C? 'varIsTrue': 'varIsFalse'}} </div>
YoBre
2
Envolverlo (A == B || A == C)
Oliver Dixon
1
Me encanta esta respuesta! El uso de directivas ng- da mucho espacio en blanco html si un div no satisface la condición ..
sksallaj
48

Angular en sí no proporciona la funcionalidad if / else, pero puede obtenerla al incluir este módulo:

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

En sus propias palabras, es solo "una simple colección de directivas de flujo de control: ng-if, ng-else-if y ng-else". Es fácil e intuitivo de usar.

Ejemplo:

<div ng-if="someCondition">
    ...
</div>
<div ng-else-if="someOtherCondition">
    ...
</div>
<div ng-else>
    ...
</div>
lpappone
fuente
1
No quiero repetir el código en div una y otra vez.
1
No tiene que repetir nada, podría hacerlo fácilmente ng-if="someCondition && someOtherCondition". Tal vez no entiendo? (Escribí ese módulo, debería funcionar igual ify elseen JS).
Zach Snow
1
Este es un salvavidas absoluto. Esto debería ser parte del núcleo angular, es indispensable en la codificación de plantillas. Mucho más limpio que tener operadores ternarios por todas partes, y supera las limitaciones de que ng-switch no pueda evaluar expresiones.
Nico Westerdale
Gracias @NicoWesterdale! Además, agregué una versión más rica de ng-switch que puede ser útil: github.com/zachsnow/ng-cases
Zach Snow
30

Puede usar su video.yt$aspectRatiopropiedad directamente pasándola a través de un filtro y vinculando el resultado al atributo de altura en su plantilla.

Su filtro se vería así:

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

Y la plantilla sería:

<video height={{video.yt$aspectRatio | videoHeight}}></video>
Noah Freitas
fuente
¿Qué tal su código cuando video.yt$aspectRatioestá vacío o indefinido? ¿Es posible aplicar un valor predeterminado?
Fractaliste
13

En este caso, desea "calcular" un valor de píxel según la propiedad de un objeto.

Definiría una función en el controlador que calcula los valores de píxeles.

En el controlador:


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

Luego, en su plantilla, simplemente escriba:


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

Estoy de acuerdo en que un ternario es extremadamente limpio. Parece que es muy situacional, aunque como algo necesito mostrar div o p o table, por lo que con una tabla no prefiero un ternario por razones obvias. Hacer una llamada a una función suele ser ideal o, en mi caso, hice esto:

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

puede usar la directiva ng-if como se indicó anteriormente.

JBhardwaj
fuente
3

Una posibilidad para Angular: tuve que incluir una declaración if en la parte html, tuve que verificar si todas las variables de una URL que produzco están definidas. Lo hice de la siguiente manera y parece ser un enfoque flexible. Espero que sea útil para alguien.

La parte html en la plantilla:

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

Y la parte mecanografiada:

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

Gracias y un saludo,

ene

Jan Clemens Stoffregen
fuente
2
Se parece más a Angular que a AngularJS.
pzaenger
@pzaenger, sí, pero muchas respuestas para esta pregunta funcionan para ambos, así que creo que algunas personas, como yo, miran las respuestas de todos modos. Avísame si te importa.
Jan Clemens Stoffregen
2
Bien. Al menos deberías mencionar esto en tu respuesta.
pzaenger
@pzaenger, gracias por esta pista, lo mencioné ahora.
Jan Clemens Stoffregen
1

ng Si otra declaración

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