condizionali incorporati in angular.js


192

Mi chiedevo se esiste un modo in angolare per visualizzare in modo condizionale contenuto diverso dall'uso di ng-show ecc. Ad esempio in backbone.js potrei fare qualcosa con il contenuto incorporato in un modello come:

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

ma in angolare, mi sembra di limitarmi a mostrare e nascondere cose racchiuse in tag html

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

Qual è il modo consigliato in angolare per mostrare e nascondere in modo condizionale il contenuto in linea in angolare usando semplicemente {{}} anziché racchiudere il contenuto in tag html?


6
per favore, accetta la mia risposta e accetta 2Toad's quando hai una possibilità.
— Ben Lesh,

Risposte:


139

EDIT: 2 La risposta di Toad di seguito è ciò che stai cercando! Valorizza quella cosa

Se stai usando Angular <= 1.1.4, questa risposta farà:

Un'altra risposta per questo. Sto postando una risposta separata, perché è più un tentativo "esatto" di una soluzione che un elenco di possibili soluzioni:

Ecco un filtro che farà un "if immediato" (aka iif):

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

e può essere usato in questo modo:

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

Grazie carne, questo è quello che stavo cercando. Tuttavia noto che se provo a inserire un tag html in uno dei valori, si rompe: {{thing.second == "two" | iif: "<ul class = 'two-class'>": "<ul>"}} Mi rendo conto che potrebbero esserci modi migliori per farlo in angolare, ma c'è un modo per sfuggire a "<" e ">" in modo che i tag possano essere emessi come parte della stringa?
— user1469779

1
ngBind non consente l'output HTML, ti consigliamo di utilizzare ng-bind-html-unsafe
— Ben Lesh

L'esempio di ng-binf-html-unsafe nella documentazione angolare lo utilizza all'interno di un tag, ad esempio <QUALSIASI ng-bind-html-unsafe = "{espressione}">. potrebbe non essere possibile fare ciò che sto cercando di fare in linea.
— user1469779

1
IIF è l'abbreviazione di "Inline If". È comune in diversi linguaggi di programmazione ... non è così comune come?: Inline ifs. ;)
— Ben Lesh,

18
@BenLesh principali oggetti di scena per modificare la tua risposta ora che ci sono altre opzioni, buon lavoro.
— Nick Coad,

725

Angular 1.1.5 ha aggiunto il supporto per gli operatori ternari:

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

14
Questa risposta con il maggior numero di voti dovrebbe apparire nella parte superiore delle risposte ... è di gran lunga la più corretta
— Code Whisperer

3
user1469779 considera di accettare questa risposta in quanto questo è il modo raccomandato per raggiungere quello che vuoi per un bel po 'di tempo
— Filip Kis

13
@ 2Toad, la mia risposta era vecchia. questa è la risposta corretta ora, non so se l'utente tornerà ad "accettarla" ora, ma ho annotato la mia risposta in quanto tale. Tale è il volto mutevole dello sviluppo del software.
— Ben Lesh,

2
Grazie. Come posso visualizzare il valore di myVarsolo se è falso? (cioè come posso annidare le variabili nell'espressione?) Ho provato con {{myVar === "two" ? "it's true" : {{myVar}}}}ma non funziona.
— Josh,

6
@Josh la myVarproprietà non ha bisogno di essere racchiusa tra parentesi graffe aggiuntive, è già dentro un'espressione. Prova{{myVar === "two" ? "it's true" : myVar}}
— ricarica il

60

Migliaia di modi per scuoiare questo gatto. Mi rendo conto che stai chiedendo in particolare tra {{}}, ma per gli altri che vengono qui, penso che valga la pena mostrare alcune delle altre opzioni.

funzione sul tuo $ scope (IMO, questa è la tua scommessa migliore nella maggior parte degli scenari):

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

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

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

ng-show e ng-hide ovviamente:

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

Un filtro personalizzato come suggerito da Bertrand. (questa è la scelta migliore se devi fare sempre la stessa cosa)

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

{{foo | myFilter}}

O una direttiva personalizzata:

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>

Personalmente, nella maggior parte dei casi andrei con una funzione sul mio ambito, mantiene il markup abbastanza pulito ed è veloce e facile da implementare. A meno che, cioè, continuerai a ripetere sempre la stessa identica cosa, nel qual caso seguirò il suggerimento di Bertrand e creerò un filtro o eventualmente una direttiva, a seconda delle circostanze.

Come sempre, la cosa più importante è che la tua soluzione è facile da mantenere ed è sperabilmente verificabile. E questo dipenderà completamente dalla tua situazione specifica.


18

Sto usando quanto segue per impostare condizionatamente la classe attr quando ng-class non può essere usata (ad esempio quando si disegna lo SVG):

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

Lo stesso approccio dovrebbe funzionare per altri tipi di attributi.

(Penso che devi essere sull'ultimo Angolare instabile per usare ng-attr-, al momento sono su 1.1.4)

Ho pubblicato un articolo su come lavorare con AngularJS + SVG che parla di questo e di problemi correlati. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS


15

Per controllare un contenuto variabile e avere un testo predefinito, è possibile utilizzare:

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

1
grazie! Ci stavo provando ma mi mancano le virgolette attorno alla stringa :-)
— Simona Adriani

Per qualsiasi motivo, questa sintassi non funziona utilizzando i collegamenti una tantum. {{:: myVar || 'Testo'}} non funzionerà. Deve essere senza:
— aoakeson il

3

Se ti ho capito bene, penso che tu abbia due modi per farlo.

Per prima cosa potresti provare ngSwitch e il secondo modo possibile sarebbe creare il tuo filtro . Probabilmente ngSwitch è l'approccio giusto, ma se vuoi nascondere o mostrare contenuti inline, basta usare il filtro {{}}.

Ecco un violino con un semplice filtro come esempio.

<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

La libreria UI angolare ha una direttiva incorporata ui-if per la condizione in template / Views fino a ui angolare 1.1.4

Esempio: supporto nell'interfaccia utente angolare fino all'interfaccia utente 1.1.4

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

ng-se disponibile in tutte le versioni angolari dopo 1.1.4

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

se hai dati nella variabile array, apparirà solo il div


ui-ifè stato rimosso almeno dall'ultima versione angular-ui ma dalla versione 1.1.5 angolare che hai ng-if(da questo commento )
— Dave Everitt,

2

Quindi con Angular 1.5.1 (la dipendenza dall'app esistente su alcune altre dipendenze dello stack MEAN è il motivo per cui non sto attualmente usando 1.6.4)

Questo funziona per me come dice il PO {{myVar === "two" ? "it's true" : "it's false"}}

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

2

se si desidera visualizzare "Nessuno" quando il valore è "0", è possibile utilizzare come:

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

o vero falso in js angolare

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

1

Funziona anche in situazioni esotiche:

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

0

Lancio il mio nel mix:

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

questo valuta una volta l'istruzione if e non aggiunge alcun listener di watch MA MA puoi aggiungere un attributo aggiuntivo all'elemento che ha il set-if chiamato wait-for = "somedata.prop" e aspetterà che i dati o la proprietà siano impostati prima valutazione dell'istruzione if una volta. quell'attributo aggiuntivo può essere molto utile se stai aspettando dati da una richiesta 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');
              });
            }
          }
        };
      }
    };
  });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.