warunkowe inline w angular.js


192

Zastanawiałem się, czy istnieje kątowy sposób warunkowego wyświetlania treści inny niż użycie ng-show itp. Na przykład w backbone.js mógłbym zrobić coś z zawartością wbudowaną w szablonie, takim jak:

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

ale pod kątem wydaje się, że ograniczam się do pokazywania i ukrywania rzeczy owiniętych w tagi HTML

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

Jaki jest zalecany sposób wyświetlania kątowego warunkowego wyświetlania i ukrywania treści wbudowanych w angularu za pomocą {{}} zamiast zawijania zawartości w tagach HTML?


6
proszę, nie akceptuj mojej odpowiedzi i zaakceptuj 2Toad, gdy pojawi się szansa.
— Ben Lesh,

Odpowiedzi:


139

EDYCJA: Odpowiedź 2Toad poniżej jest tym, czego szukasz! Głosuj za tym

Jeśli używasz Angulara <= 1.1.4, ta odpowiedź zrobi:

Jeszcze jedna odpowiedź na to. Podaję osobną odpowiedź, ponieważ jest to bardziej „dokładna” próba rozwiązania niż lista możliwych rozwiązań:

Oto filtr, który wykona „natychmiastowe, jeśli” (alias iif):

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

i mogą być używane w następujący sposób:

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

Dziękuję, kochanie, po to właśnie chciałem. Zauważam jednak, że jeśli spróbuję umieścić znacznik HTML w jednej z wartości, psuje się: {{thing.second == "two" | iif: "<ul class = 'two-class'>": "<ul>"}} Zdaję sobie sprawę, że mogą istnieć lepsze sposoby na zrobienie tego pod kątem, ale czy istnieje sposób na ucieczkę "<" i ">" aby tagi mogły być wyprowadzane jako część ciągu?
— user1469779,

1
ngBind nie pozwala na wyjście HTML, chciałbyś użyć ng-bind-html-unsafe
— Ben Lesh

Przykład ng-binf-html-unsafe w dokumentacji kątowej używa go w znaczniku, na przykład <DOWOLNY ng-bind-html-unsafe = "{wyrażenie}">. może nie być możliwe robienie tego, co próbuję zrobić inline.
— user1469779,

1
IIF to skrót od „Inline If”. Jest powszechny w różnych językach programowania ... po prostu nie tak powszechny jak?: Wbudowane ifs. ;)
— Ben Lesh

18
@BenLesh główne rekwizyty do edycji odpowiedzi teraz, gdy są inne opcje, dobra robota.
— Nick Coad

724

Dodano obsługę Angular 1.1.5 dla operatorów trójskładnikowych:

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

14
Ta odpowiedź z największą liczbą głosów powinna znaleźć się u góry odpowiedzi ... jest zdecydowanie najbardziej poprawna
— Code Whisperer

3
user1469779 rozważ zaakceptowanie tej odpowiedzi, ponieważ jest to zalecany sposób osiągnięcia tego, czego chcesz od dłuższego czasu
— Filip Kis,

13
@ 2Toad, moja odpowiedź była stara. to jest prawidłowa odpowiedź teraz, nie wiem, czy użytkownik wróci, by ją „zaakceptować” teraz, ale jako taką opatrzyłem adnotację. Takie jest zmieniające się oblicze rozwoju oprogramowania.
— Ben Lesh,

2
Dzięki. Jak mogę wyświetlać wartość myVartylko wtedy, gdy jest fałszywa? (tzn. jak zagnieżdżać zmienne w wyrażeniu?) Próbowałem z, {{myVar === "two" ? "it's true" : {{myVar}}}}ale to nie działa.
— Josh

6
@Josh, myVarwłaściwość nie musi być zawijana w dodatkowe nawiasy klamrowe, jest już w wyrażeniu. Spróbuj{{myVar === "two" ? "it's true" : myVar}}
— 2Toad

60

Tysiące sposobów na skórowanie tego kota. Zdaję sobie sprawę, że pytasz konkretnie o {{}}, ale dla innych, którzy tu przychodzą, myślę, że warto pokazać inne opcje.

funkcja na $ zakres (IMO, to jest twój najlepszy zakład w większości scenariuszy):

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

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

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

ng-show i ng-hide oczywiście:

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

Filtr niestandardowy, jak sugerował Bertrand. (jest to najlepszy wybór, jeśli musisz robić to samo w kółko)

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

{{foo | myFilter}}

Lub niestandardowa dyrektywa:

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>

Osobiście w większości przypadków korzystałbym z funkcji w moim zasięgu, która utrzymuje znaczniki w czystości, a jego wdrożenie jest szybkie i łatwe. Chyba że, to znaczy, będziesz robić to samo od nowa w kółko, w takim przypadku skorzystałbym z sugestii Bertranda i stworzyłbym filtr lub ewentualnie dyrektywę, w zależności od okoliczności.

Jak zawsze najważniejsze jest to, że Twoje rozwiązanie jest łatwe w utrzymaniu i, mam nadzieję, że można je przetestować. A to całkowicie zależy od konkretnej sytuacji.


18

Korzystam z następujących opcji, aby warunkowo ustawić klasę attr, gdy nie można użyć klasy ng (na przykład podczas stylowania SVG):

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

To samo podejście powinno działać w przypadku innych typów atrybutów.

(Myślę, że musisz używać najnowszego niestabilnego Angulara, aby używać ng-attr-, aktualnie jestem na wersji 1.1.4)

Opublikowałem artykuł o pracy z AngularJS + SVG, który mówi o tym i powiązanych zagadnieniach. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS


15

Aby sprawdzić zmienną zawartość i mieć domyślny tekst, możesz użyć:

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

1
Dziękuję Ci! Próbowałem tego, ale brakuje mi cytatów wokół łańcucha :-)
— Simona Adriani

Z jakiegokolwiek powodu ta składnia nie działa przy użyciu jednorazowych powiązań. {{:: myVar || „Tekst”}} nie będzie działać. Musi być bez ::
— aoakeson

3

Jeśli dobrze cię zrozumiałem, myślę, że masz na to dwa sposoby.

Najpierw możesz wypróbować ngSwitch, a drugim możliwym sposobem byłoby stworzenie własnego filtra . Prawdopodobnie ngSwitch jest właściwym podejściem, ale jeśli chcesz ukryć lub pokazać zawartość wbudowaną tylko za pomocą filtra {{}}, możesz to zrobić.

Oto skrzypce z prostym filtrem jako przykładem.

<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

Biblioteka Angular UI ma wbudowaną dyrektywę ui-if dla warunku w szablonie / Widoki do angular ui 1.1.4

Przykład: Wsparcie w Angular UI upto ui 1.1.4

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

ng-jeśli jest dostępny we wszystkich wersjach kątowych po 1.1.4

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

jeśli masz jakieś dane w zmiennej tablicowej, pojawi się tylko div


ui-ifzostał usunięty przynajmniej z najnowszej wersji angular-ui, ale od wersji kątowej 1.1.5 masz ng-if(z tego komentarza )
— Dave Everitt 28.10.13

2

Tak więc w Angular 1.5.1 (istniała zależność aplikacji od niektórych innych zależności stosu MEAN, dlatego obecnie nie używam 1.6.4)

Działa to dla mnie, jak mówi OP {{myVar === "two" ? "it's true" : "it's false"}}

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

2

jeśli chcesz wyświetlić „Brak”, gdy wartość wynosi „0”, możesz użyć jako:

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

lub true false w kątowym js

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

1

Działa nawet w egzotycznych sytuacjach:

<br ng-show="myCondition == true" />

0

Wrzucę moje do miksu:

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

ocenia to raz instrukcję if i nie dodaje nasłuchiwania, ALE można dodać dodatkowy atrybut do elementu, który ma zestaw-if o nazwie wait-for = "somedata.prop" i będzie czekał na ustawienie tych danych lub właściwości przed jednorazowa ocena instrukcji if. ten dodatkowy atrybut może być bardzo przydatny, jeśli czekasz na dane z żądania 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');
              });
            }
          }
        };
      }
    };
  });
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.