оператор if else в шаблонах AngularJS

702

Я хочу сделать условие в шаблоне AngularJS. Я получаю список видео из YouTube API. Некоторые видео имеют соотношение 16: 9, а некоторые - 4: 3.

Я хочу сделать условие, как это:

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

Я перебираю видео используя ng-repeat. Понятия не имею, что мне делать для этого условия:

  • Добавить функцию в область?
  • Сделать это в шаблоне?
vzhen
источник
2
Я нашел одну статью нг-если здесь. goo.gl/wQ30uf
вирендер

Ответы:

1284

Angularjs (версии ниже 1.1.5) не обеспечивает if/elseфункциональность. Ниже приведены несколько вариантов, которые вы можете рассмотреть:

( Перейти к обновлению ниже (# 5), если вы используете версию 1.1.5 или выше )

1. Тернарный оператор:

Как предложено @Kirk в комментариях, самый простой способ сделать это - использовать троичный оператор следующим образом:

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

2. ng-switchдиректива:

может быть использовано что-то вроде следующего.

<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директивы

В качестве альтернативы вы также можете использовать, ng-show/ng-hideно, используя это, вы фактически отрендерите и большое видео, и маленький видеоэлемент, а затем скроете тот, который соответствует ng-hideусловию, и покажет тот, который соответствует ng-showусловию. Таким образом, на каждой странице вы будете отображать два разных элемента.

4. Другим вариантом для рассмотрения является ng-classдиректива.

Это можно использовать следующим образом.

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

Вышесказанное в основном добавит large-videoкласс css к элементу div, если video.largeэто правда.

ОБНОВЛЕНИЕ: Angular 1.1.5 представилngIf directive

5. ng-ifдиректива:

В версиях выше 1.1.5вы можете использовать ng-ifдирективу. Это удалит элемент, если возвращенное выражение вернет, falseи повторно вставит elementв DOM, если выражение вернется true. Можно использовать следующим образом.

<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>
Amyth
источник
9
Это должно быть ng-switch on="video"вместоng-switch-on="video"
czerasz
4
Как это сделать? if () {} else if () {} else if () {} else {} Но
включите
208
Также троичный<span>{{isAdded ? 'Added' : 'Add to cart'}}</span>
Кирк Стробек
16
Имейте в виду, что ng-ifНЕ будет добавлять вложенные элементы в DOM, пока его состояние не будет оценено true, в отличие от ng-hideи ng-show.
Вильгельм Мердок
1
Почему не просто ng-switch="video"? Небольшая проблема? или это было недоступно ранее? Для меня это работает вполне нормально
Сами
175

В последней версии Angular (по состоянию на 1.1.5) они включили условную директиву под названием ngIf. Он отличается от ngShowи ngHideв том , что элементы не скрыты, но не включены в DOM вообще. Они очень полезны для компонентов, которые стоят дорого, но не используются:

<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>
Брайан Дженисио
источник
5
Имейте в виду, что ng-ifвводит изолированную область , так что $parentстановится $parent.$parentв теле ng-if.
Дэвид Саламон
142

Тройной путь - самый ясный способ сделать это.

<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
Оливер Диксон
источник
Хо, чтобы сделать это с 2 условия в или ?? как <div> {{A == B || A == C? 'varIsTrue': 'varIsFalse'}} </ div>
Йобр
2
Оберните это (A == B || A == C)
Оливер Диксон
1
люблю этот ответ! Использование директив ng дает большое количество пробелов в html, если div не удовлетворяет условию ..
sksallaj
48

Сам Angular не предоставляет функциональность if / else, но вы можете получить ее, включив этот модуль:

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

По его словам, это просто «простая коллекция директив потока управления: ng-if, ng-else-if и ng-else». Это простой и интуитивно понятный в использовании.

Пример:

<div ng-if="someCondition">
    ...
</div>
<div ng-else-if="someOtherCondition">
    ...
</div>
<div ng-else>
    ...
</div>
lpappone
источник
1
я не хочу повторять код в div снова и снова.
1
Вам не нужно ничего повторять - вы могли бы так же легко это сделать ng-if="someCondition && someOtherCondition". Возможно, я неправильно понимаю? (Я написал этот модуль - он должен работать так же, как ifи elseв JS).
Зак Сноу
1
Это абсолютный спасатель. Это должно быть частью ядра Angular, оно незаменимо при кодировании шаблонов. Это намного чище, чем использование троичных операторов повсюду, и преодолевает ограничения, связанные с невозможностью вычисления выражений в ng-switch.
Нико
Спасибо @NicoWesterdale! Кроме того, я добавил более богатую версию ng-switch, которая может оказаться полезной: github.com/zachsnow/ng-cases
Zach Snow,
30

Вы можете использовать свое video.yt$aspectRatioсвойство напрямую, пропустив его через фильтр и связав результат с атрибутом высоты в вашем шаблоне.

Ваш фильтр будет выглядеть примерно так:

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

И шаблон будет:

<video height={{video.yt$aspectRatio | videoHeight}}></video>
Ной Фрейтас
источник
Как насчет вашего кода, когда video.yt$aspectRatioон пуст или не определен? Можно ли применить значение по умолчанию?
Фракталист
13

В этом случае вы хотите «вычислить» значение пикселя в зависимости от свойства объекта.

Я бы определил функцию в контроллере, которая вычисляет значения пикселей.

В контроллере:


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

Тогда в вашем шаблоне вы просто пишете:


element height="{{ GetHeight(aspect) }}px "
Спок
источник
11

Я согласен, что троичный очень чист. Кажется, что это очень ситуативно, хотя в некоторых случаях мне нужно отображать div или p или таблицу, поэтому с таблицей я не предпочитаю троичную по очевидным причинам. Выполнение вызова функции обычно идеально, или в моем случае я сделал это:

<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>
Том Стиккель
источник
4
    <div ng-if="modeldate==''"><span ng-message="required" class="change">Date is required</span> </div>

Вы можете использовать директиву ng-if, как указано выше.

JBhardwaj
источник
3

Возможность для Angular: мне нужно было включить оператор if - в html-часть, я должен был проверить, определены ли все переменные URL, который я создаю. Я сделал это следующим образом, и это, кажется, гибкий подход. Я надеюсь, что это будет полезно для кого-то.

HTML часть в шаблоне:

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

И машинописная часть:

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

Спасибо и всего наилучшего,

январь

Ян Клеменс Стоффреген
источник
2
Больше похоже на Angular, чем AngularJS.
pzaenger
@pzaenger, да, но многие ответы на этот вопрос работают для обоих, поэтому я думаю, что некоторые люди, как и я, все равно смотрят на ответы. Пожалуйста, дайте мне знать, если вы не возражаете.
Ян Клеменс Стоффреген
2
Хорошо. По крайней мере, вы должны упомянуть об этом в своем ответе.
pzaenger
@pzaenger, спасибо за эту подсказку, я уже упоминал об этом.
Ян Клеменс Стоффреген,
1

нг Если еще заявление

ng-if="receiptData.cart == undefined ? close(): '' ;"
Амир Анвар
источник