instrukcja else jeśli w szablonach AngularJS

702

Chcę wykonać warunek w szablonie AngularJS. Pobieram listę filmów z interfejsu API YouTube. Niektóre filmy są w proporcjach 16: 9, a niektóre w proporcjach 4: 3.

Chcę wprowadzić taki stan:

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

Używam iteracji filmów ng-repeat. Nie mam pojęcia, co powinienem zrobić dla tego warunku:

  • Dodać funkcję w zakresie?
  • Czy to w szablonie?
Shenzhen
źródło
2
Znalazłem tutaj jeden artykuł ng-if. goo.gl/wQ30uf
virender

Odpowiedzi:

1284

Angularjs (wersje poniżej 1.1.5) nie zapewnia tej if/elsefunkcjonalności. Poniżej znajduje się kilka opcji do rozważenia, co chcesz osiągnąć:

( Przejdź do aktualizacji poniżej (# 5), jeśli używasz wersji 1.1.5 lub nowszej )

1. Operator trójskładnikowy:

Jak sugeruje @Kirk w komentarzach, najczystszym sposobem na zrobienie tego byłoby użycie operatora trójskładnikowego w następujący sposób:

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

2. ng-switchdyrektywa:

można użyć czegoś takiego jak poniżej.

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

Alternatywnie możesz również użyć, ng-show/ng-hideale użycie tego spowoduje wyrenderowanie zarówno dużego wideo, jak i małego elementu wideo, a następnie ukryje ten, który spełnia ng-hidewarunek i pokazuje ten, który spełnia ng-showwarunek. Na każdej stronie będziesz renderować dwa różne elementy.

4. Inną opcją do rozważenia jest ng-classdyrektywa.

Można to wykorzystać w następujący sposób.

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

Powyższe w zasadzie doda large-videoklasę css do elementu div, jeśli video.largejest to prawdą.

AKTUALIZACJA: Angular 1.1.5 wprowadziłngIf directive

5. ng-ifdyrektywa:

W powyższych wersjach 1.1.5możesz skorzystać z ng-ifdyrektywy. Spowoduje to usunięcie elementu, jeśli podane wyrażenie zwróci falsei ponownie wstawi elementelement DOM, jeśli wyrażenie zostanie zwrócone true. Może być używany w następujący sposób.

<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>
Mit
źródło
9
Powinno być ng-switch on="video"zamiastng-switch-on="video"
czerasz
4
Jak to zrobić if () {} else if () {} else if () {} else {} Ale uwzględnij w dom tylko jeden element
falko
208
Również trójskładnikowy<span>{{isAdded ? 'Added' : 'Add to cart'}}</span>
Kirk Strobeck
16
Należy pamiętać, że ng-ifNIE doda zamkniętych elementów do DOM, dopóki jego stan nie zostanie oceniony true, w przeciwieństwie do ng-hidei ng-show.
Wilhelm Murdoch,
1
Dlaczego nie po prostu ng-switch="video"? Pewien problem? czy nie był wcześniej dostępny? Dla mnie to działa całkiem dobrze
Sami
175

W najnowszej wersji Angulara (od 1.1.5) wprowadzono dyrektywę warunkową o nazwie ngIf. To różni się od ngShowi ngHidetym, że elementy nie są ukryte, ale nie ujęte w DOM w ogóle. Są bardzo przydatne w przypadku komponentów, których tworzenie jest kosztowne, ale nie są używane:

<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>
Brian Genisio
źródło
5
Należy pamiętać, że ng-ifwprowadza izolowany zakres , dzięki czemu $parentstaje się $parent.$parentw ciele ng-if.
David Salamon,
142

Trójskładnik jest najwyraźniejszym sposobem na zrobienie tego.

<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
Oliver Dixon
źródło
Ho to zrobić z 2 warunkami w lub ?? jak <div> {{A == B || A == C? „varIsTrue”: „varIsFalse”}} </div>
YoBre
2
Owiń to (A == B || A == C)
Oliver Dixon
1
uwielbiam tę odpowiedź! Użycie dyrektyw ng daje wiele białych znaków HTML, jeśli div nie spełnia warunku ..
sksallaj,
48

Sam Angular nie zapewnia funkcjonalności if / else, ale można ją uzyskać, włączając ten moduł:

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

Innymi słowy, jest to po prostu „prosty zbiór dyrektyw dotyczących przepływu kontroli: ng-if, ng-else-if i ng-else”. Jest łatwy i intuicyjny w użyciu.

Przykład:

<div ng-if="someCondition">
    ...
</div>
<div ng-else-if="someOtherCondition">
    ...
</div>
<div ng-else>
    ...
</div>
lpappone
źródło
1
Nie chcę powtarzać kodu w div raz po raz.
1
Nie musisz nic powtarzać - równie łatwo możesz to zrobić ng-if="someCondition && someOtherCondition". Być może źle zrozumiałem? (Napisałem ten moduł - to powinno działać tak jak ifi elsew JS).
Zach Snow
1
To absolutny ratownik. Powinno to być częścią Angular core, jest niezbędne w kodowaniu szablonów. Znacznie czystsze niż posiadanie operatorów trójskładnikowych w całym miejscu i przezwycięża ograniczenia związane z niemożnością oceny wyrażeń przez przełącznik ng-switch.
Nico Westerdale,
Dzięki @NicoWesterdale! Dodałem także bogatszą wersję przełącznika ng, który może ci się przydać: github.com/zachsnow/ng-cases
Zach Snow
30

Możesz użyć swojej video.yt$aspectRatiowłaściwości bezpośrednio, przepuszczając ją przez filtr i wiążąc wynik z atrybutem wysokości w szablonie.

Twój filtr wyglądałby mniej więcej tak:

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

A szablon będzie:

<video height={{video.yt$aspectRatio | videoHeight}}></video>
Noah Freitas
źródło
Co powiesz na kod, który video.yt$aspectRatiojest pusty lub niezdefiniowany? Czy można zastosować wartość domyślną?
Fractaliste
13

W takim przypadku chcesz „obliczyć” wartość piksela w zależności od właściwości obiektu.

Zdefiniowałbym funkcję w kontrolerze, która oblicza wartości pikseli.

W kontrolerze:


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

Następnie w swoim szablonie po prostu piszesz:


element height="{{ GetHeight(aspect) }}px "

Spock
źródło
11

Zgadzam się, że trójskładnik jest wyjątkowo czysty. Wydaje się, że jest to bardzo sytuacyjne, ponieważ muszę wyświetlać div, p lub table, więc z tabelą nie wolę trójki z oczywistych powodów. Wywołanie funkcji jest zazwyczaj idealne lub w moim przypadku zrobiłem to:

<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>
Tom Stickel
źródło
4
    <div ng-if="modeldate==''"><span ng-message="required" class="change">Date is required</span> </div>

możesz użyć dyrektywy ng-if jak wyżej.

JBhardwaj
źródło
3

Możliwość dla Angulara: Musiałem zawrzeć instrukcję if - w części HTML, musiałem sprawdzić, czy wszystkie zmienne adresu URL, który tworzę, są zdefiniowane. Zrobiłem to w następujący sposób i wydaje się, że jest to elastyczne podejście. Mam nadzieję, że komuś się przyda.

Część HTML w szablonie:

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

I część maszynopisu:

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

Dziękuję i pozdrawiam,

Jan

Jan Clemens Stoffregen
źródło
2
Wygląda bardziej jak Angular niż AngularJS.
pzaenger
@pzaenger, tak, ale wiele odpowiedzi na to pytanie działa na oba, więc myślę, że niektórzy ludzie, jak ja, i tak patrzą na odpowiedzi. Daj mi znać, jeśli masz coś przeciwko.
Jan Clemens Stoffregen
2
Dobrze. Przynajmniej powinieneś wspomnieć o tym w swojej odpowiedzi.
pzaenger
@pzaenger, dziękuję za tę wskazówkę, wspomniałem o tym teraz.
Jan Clemens Stoffregen
1

ng Jeśli inaczej

ng-if="receiptData.cart == undefined ? close(): '' ;"
Aamir Anwar
źródło