вбудовані умови в angular.js


192

Мені було цікаво, чи є спосіб у певному режимі умовно відображати вміст, відмінний від використання ng-show тощо. Наприклад, у backbone.js я можу зробити щось із вбудованим вмістом у шаблоні на кшталт:

<% if (myVar === "two") { %> show this<% } %>

але в кутовому плані я, здається, обмежений показ і приховування речей, загорнутих у HTML-теги

<p ng-hide="true">I'm hidden</p>
<p ng-show="true">I'm shown</p>

Який рекомендований спосіб у куті умовно показувати та приховувати вбудований вміст у кутовому просто за допомогою {{}}, а не загортати вміст у HTML-теги?


6
будь ласка, не приймайте мою відповідь, приймайте 2Toad, коли у вас є можливість.
Бен Леш

Відповіді:


139

EDIT: 2 відповідь теми нижче - це те, що ви шукаєте! Підкресліть цю річ

Якщо ви використовуєте Angular <= 1.1.4, ця відповідь виконає:

Ще одна відповідь на це. Я публікую окрему відповідь, оскільки це скоріше "точна" спроба рішення, ніж перелік можливих рішень:

Ось фільтр, який зробить "негайно" (aka iif):

app.filter('iif', function () {
   return function(input, trueValue, falseValue) {
        return input ? trueValue : falseValue;
   };
});

і може використовуватися так:

{{foo == "bar" | iif : "it's true" : "no, it's not"}}

Спасибі тобі, це я йшов. Однак я помічаю, що якщо я спробую поставити тег html в одне зі значень, яке воно порушує: {{thing.second == "two" | iif: "<ul class = 'two-class'>": "<ul>"}} Я розумію, що можуть бути кращі способи зробити це в кутовому порядку, але чи є спосіб уникнути "<" і ">" щоб теги могли виводитися як частина рядка?
користувач1469779

1
ngBind не дозволяє виводити HTML, ви хочете використовувати ng-bind-html-unsafe
Бен Леш

Приклад ng-binf-html-unsafe в кутовій документації використовує його в тезі, наприклад <ANY ng-bind-html-unsafe = "{izraz}">. це може бути неможливо зробити те, що я намагаюся робити в Інтернеті.
користувач1469779

1
IIF - це абревіатура для "Inline If". Він поширений у різних мовах програмування ... просто не так часто, як ?: inline ifs. ;)
Бен Леш

18
@BenLesh основні реквізити для редагування вашої відповіді тепер, коли є інші варіанти, хороша робота.
Нік Код

725

Кутова 1.1.5 додала підтримку потрійних операторів:

{{myVar === "two" ? "it's true" : "it's false"}}

14
Ця відповідь із найбільшою кількістю результатів повинна з’явитися у верхній частині відповідей ... вона, безумовно, найправильніша
Шепіт коду

3
користувач1469779 розглядає можливість прийняти цю відповідь, оскільки це рекомендований спосіб досягти того, чого ви хочете протягом досить тривалого часу
Filip Kis

13
@ 2Toad, моя відповідь була старою. це правильна відповідь зараз, я не знаю, чи повернеться користувач до "прийняття" його зараз, але я відзначив свою відповідь як таку. Таке мінливе обличчя розробки програмного забезпечення.
Бен Леш

2
Дякую. Як я можу, щоб воно відображало значення myVarлише у тому випадку, якщо воно неправдиве? (тобто як я можу вкласти змінні в виразі?) Я намагався, {{myVar === "two" ? "it's true" : {{myVar}}}}але це не працює.
Джош

6
@Josh myVarвластивість не потрібно загортати в додаткові фігурні дужки, це вже всередині виразу. Спробуйте{{myVar === "two" ? "it's true" : myVar}}
2

60

Тисячі способів шкіри цього кота. Я усвідомлюю, що ви питаєте про {{}} спеціально, але для інших, хто приходить сюди, я думаю, що варто показати деякі інші варіанти.

функція у вашому діапазоні $ (IMO, це найкраща ставка у більшості сценаріїв):

  app.controller('MyCtrl', function($scope) {
      $scope.foo = 1;

      $scope.showSomething = function(input) {
           return input == 1 ? 'Foo' : 'Bar';
      };
   });

 <span>{{showSomething(foo)}}</span>

ng-show та ng-сховати звичайно:

 <span ng-show="foo == 1">Foo</span><span ng-hide="foo == 1">Bar</span>

ngSwitch

 <div ng-switch on="foo">
   <span ng-switch-when="1">Foo</span>
   <span ng-switch-when="2">Bar</span>
   <span ng-switch-default>What?</span>
 </div>

Спеціальний фільтр, як запропонував Бертран. (це ваш найкращий вибір, якщо вам доведеться робити те ж саме знову і знову)

app.filter('myFilter', function() {
   return function(input) {
     return input == 1 ? 'Foo' : 'Bar';
   }
}

{{foo | myFilter}}

Або спеціальна директива:

app.directive('myDirective', function() {
   return {
     restrict: 'E',
     replace: true,
     link: function(scope, elem, attrs) {
       scope.$watch(attrs.value, function(v) {
          elem.text(v == 1 ? 'Foo': 'Bar');
       });
     }
   };
});


<my-directive value="foo"></my-directive>

Особисто я в більшості випадків використовую функцію в моєму просторі, і це забезпечує розмітку досить чистою, і її швидко та просто реалізувати. Якщо тільки, тобто, ви будете робити те саме саме і знову і знову, і в такому випадку я б пішов із пропозицією Бертранда і створив фільтр чи, можливо, директиву, залежно від обставин.

Як завжди, найважливіше - це те, що ваше рішення просте у обслуговуванні , і, маємо надію, перевірити. І це буде повністю залежати від вашої конкретної ситуації.


18

Я використовую наступне для умовного встановлення класу attr, коли ng-class не може бути використаний (наприклад, для стилю SVG):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

Цей же підхід повинен працювати і для інших типів атрибутів.

(Я думаю, що вам потрібно мати останній нестабільний Angular, щоб використовувати ng-attr-, я зараз на 1.1.4)

Я опублікував статтю про роботу з AngularJS + SVG, яка розповідає про це та пов'язані з цим проблеми. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS


15

Для перевірки змінного вмісту та тексту за замовчуванням ви можете використовувати:

<span>{{myVar || 'Text'}}</span>

1
спасибі! Я намагався це зробити, але пропускаю цитати навколо рядка :-)
Симона Адріані

З будь-якої причини цей синтаксис не працює, використовуючи одноразові прив’язки .. {{:: myVar || 'Текст'}} не працюватиме. Повинен бути без ::
aoakeson

3

Якщо я вас добре зрозумів, я думаю, що у вас є два способи.

Спочатку ви можете спробувати ngSwitch, а другий можливий спосіб - створити власний фільтр . Ймовірно, ngSwitch є правильним підходом, але якщо ви хочете приховати або показати вбудований вміст, просто використовуючи {{}} фільтр - це шлях.

Ось загадка з простим фільтром як приклад.

<div ng-app="exapleOfFilter">
  <div ng-controller="Ctrl">
    <input ng-model="greeting" type="greeting">
      <br><br>
      <h1>{{greeting|isHello}}</h1>
  </div>
</div>

angular.module('exapleOfFilter', []).
  filter('isHello', function() {
    return function(input) {
      // conditional you want to apply
      if (input === 'hello') {
        return input;
      }
      return '';
    }
  });

function Ctrl($scope) {
  $scope.greeting = 'hello';
}

3

Кутова бібліотека користувальницького інтерфейсу має вбудовану директиву ui-if для умови в шаблоні / Views до кутового ui 1.1.4

Приклад: Підтримка у кутовому інтерфейсі upto ui 1.1.4

<div ui-if="array.length>0"></div>

ng-якщо є доступна у всіх кутових версіях після 1.1.4

<div ng-if="array.length>0"></div>

якщо у вас є будь-які дані в змінній масиві, тоді з'явиться лише div


ui-ifбуло видалено принаймні з останньої версії angular-ui, але оскільки у куті 1.1.5 у вас є ng-ifцього коментаря )
Дейв Еверітт

2

Так з кутовим 1.5.1 (якщо існувала залежність програми від деяких інших стеків MEAN, тому я зараз не використовую 1.6.4)

Це працює для мене, як приказка ОП {{myVar === "two" ? "it's true" : "it's false"}}

{{vm.StateName === "AA" ? "ALL" : vm.StateName}}

2

якщо ви хочете відобразити "None", коли значення "0", ви можете використовувати як:

<span> {{ $scope.amount === "0" ?  $scope.amount : "None" }} </span>

або істинна помилка у кутовому js

<span> {{ $scope.amount === "0" ?  "False" : "True" }} </span>


0

Я кину мою в суміш:

https://gist.github.com/btm1/6802312

це оцінює оператор if один раз і не додає слухача годинника, АЛЕ ви можете додати додатковий атрибут до елемента, який має набір - якщо його називають wait-for = "somedata.prop", і він буде чекати, коли ці дані або властивість будуть встановлені раніше оцінку оператора if один раз. цей додатковий атрибут може бути дуже зручним, якщо ви чекаєте даних із запиту XHR.

angular.module('setIf',[]).directive('setIf',function () {
    return {
      transclude: 'element',
      priority: 1000,
      terminal: true,
      restrict: 'A',
      compile: function (element, attr, linker) {
        return function (scope, iterStartElement, attr) {
          if(attr.waitFor) {
            var wait = scope.$watch(attr.waitFor,function(nv,ov){
              if(nv) {
                build();
                wait();
              }
            });
          } else {
            build();
          }

          function build() {
            iterStartElement[0].doNotMove = true;
            var expression = attr.setIf;
            var value = scope.$eval(expression);
            if (value) {
              linker(scope, function (clone) {
                iterStartElement.after(clone);
                clone.removeAttr('set-if');
                clone.removeAttr('wait-for');
              });
            }
          }
        };
      }
    };
  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.