Тернарный оператор в шаблонах AngularJS


239

Как вы делаете троичный с AngularJS (в шаблонах)?

Было бы неплохо использовать некоторые атрибуты html (классы и стиль) вместо создания и вызова функции контроллера.

Ответы:


374

Обновление : Angular 1.1.5 добавил троичный оператор , так что теперь мы можем просто написать

<li ng-class="$first ? 'firstRow' : 'nonFirstRow'">

Если вы используете более раннюю версию Angular, у вас есть два варианта:

  1. (condition && result_if_true || !condition && result_if_false)
  2. {true: 'result_if_true', false: 'result_if_false'}[condition]

пункт 2. выше создает объект с двумя свойствами. Синтаксис массива используется для выбора либо свойства с именем true, либо свойства с именем false и возврата соответствующего значения.

Например,

<li class="{{{true: 'myClass1 myClass2', false: ''}[$first]}}">...</li>
 or
<li ng-class="{true: 'myClass1 myClass2', false: ''}[$first]">...</li>

Для $ first установлено значение true внутри ng-repeat для первого элемента, поэтому приведенное выше применило бы классы 'myClass1' и 'myClass2' только первый раз в цикле.

С ng-class есть более простой способ: ng-class принимает выражение, которое должно принимать одно из следующих значений:

  1. строка имен классов, разделенных пробелами
  2. массив имен классов
  3. карта / объект имен классов для логических значений.

Пример 1) был приведен выше. Вот пример 3, который, я думаю, читается намного лучше:

 <li ng-class="{myClass: $first, anotherClass: $index == 2}">...</li>

В первый раз через цикл ng-repeat добавляется класс myClass. В третий раз ($ index начинается с 0) добавляется класс anotherClass.

ng-style принимает выражение, которое должно соответствовать карте / объекту с именами стилей CSS и значениями CSS. Например,

 <li ng-style="{true: {color: 'red'}, false: {}}[$first]">...</li>

6
Если бы я мог, я бы снова проголосовал за обновление вопроса!
Наррец

2
Я позабочусь об этом, @Narretz.
Ян Хантер

1
В примере доступа к объектному ключу вы можете пропустить «ложный» ключ, так как в любом случае это пустая строка.
0xc0de

Слово предупреждения, 1.1.5 в настоящее время не является стабильным.
Адам Грант

Что делать, если условие изменяется при обновлении модели? Я хотел бы ng-styleобновить, но, похоже, он будет оцениваться только при первом отображении элемента. (Угловой нуб здесь)
Хартли Броуди

86

Обновление: в Angular 1.1.5 добавлен троичный оператор, этот ответ верен только для версий, предшествующих 1.1.5. Для версии 1.1.5 и более поздних версий см. Принятый в настоящее время ответ.

До Angular 1.1.5:

Форма тройного в angularjs это:

((condition) && (answer if true) || (answer if false))

Примером может быть:

<ul class="nav">
    <li>
        <a   href="#/page1" style="{{$location.path()=='/page2' && 'color:#fff;' || 'color:#000;'}}">Goals</a>
    </li>
    <li>
        <a   href="#/page2" style="{{$location.path()=='/page2' && 'color:#fff;' || 'color:#000;'}}">Groups</a>
    </li>
</ul>

или:

 <li  ng-disabled="currentPage == 0" ng-click="currentPage=0"  class="{{(currentPage == 0) && 'disabled' || ''}}"><a> << </a></li>

1
Weird. Это не очень интуитивно понятно. Интересно, почему это было реализовано таким образом?
Бен Леш

4
Ternary никогда не был реализован, но он просто использует бинарные операторы так, как они работают.
Эндрю Джослин

18
@blesh, AngularJS способствует тестируемости. Шаблоны не должны содержать никакой логики. Тернарный оператор в шаблоне должен быть преобразован в вызов функции контроллера для лучшей тестируемости.
Марчелло Нуччо

1
@ arg20 вы должны использовать директиву ngClass (или ngClassEven и ngClassOdd). Затем поместите всю логику для выбора классов CSS в контроллере. Это гораздо проще проверить автоматически.
Марчелло Нуччо

1
@ arg20 Я сказал, чтобы положить его в контроллере, а не в модели. Это не должно быть проблемой. Тем не менее, в документации сказано: «Результатом оценки может быть строка, представляющая имена классов, разделенные пробелами, массив или карта имен классов с логическими значениями». Это означает, что вы можете использовать "{cssclass: someBoolCheck ()}" в качестве выражения, т.е. вы помещаете класс css в представление и логику в контроллере. Посмотрите на этот jsFiddle для примера.
Марчелло Нуччо

23

Для текстов в угловом шаблоне ( userTypeэто свойство $ scope, например $ scope.userType):

<span>
  {{userType=='admin' ? 'Edit' : 'Show'}}
</span>

11

К настоящему времени все мы узнали, что версия 1.1.5 имеет правильную троицу в $parseфункции, поэтому просто используйте этот ответ в качестве примера фильтров:

angular.module('myApp.filters', [])

  .filter('conditional', function() {
    return function(condition, ifTrue, ifFalse) {
      return condition ? ifTrue : ifFalse;
    };
  });

А затем использовать его как

<i ng-class="checked | conditional:'icon-check':'icon-check-empty'"></i>

2
Я пришел к этому вопросу для троичного оператора, но в конце я пошел с фильтром, и это было действительно хорошо ... = D
slacktracer



0
  <body ng-app="app">
  <button type="button" ng-click="showme==true ? !showme :showme;message='Cancel Quiz'"  class="btn btn-default">{{showme==true ? 'Cancel Quiz': 'Take a Quiz'}}</button>
    <div ng-show="showme" class="panel panel-primary col-sm-4" style="margin-left:250px;">
      <div class="panel-heading">Take Quiz</div>
      <div class="form-group col-sm-8 form-inline" style="margin-top: 30px;margin-bottom: 30px;">

        <button type="button" class="btn btn-default">Start Quiz</button>
      </div>
    </div>
  </body>

Кнопка переключения и изменения заголовка кнопки и показать / скрыть панель Div. Смотреть Plunkr

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.