web-dev-qa-db-de.com

was ist der Unterschied zwischen ng-if und ng-show/ng-hide

Ich versuche den Unterschied zwischen ng-if und ng-show/ng-hide zu verstehen, aber sie sehen für mich gleich aus.

Gibt es einen Unterschied, den ich berücksichtigen sollte, wenn ich mich für die eine oder die andere entscheiden sollte?

408

ngIf

Die ngIf-Direktive entfernt oder erstellt einen Teil der DOM-Struktur basierend auf einem Ausdruck. Wenn der Ausdruck, der ngIf zugewiesen ist, einen falschen Wert ergibt, wird das Element aus dem DOM entfernt. Andernfalls wird ein Klon des Elements erneut in das DOM eingefügt.

<!-- when $scope.myValue is truthy (element is restored) -->
<div ng-if="1"></div>

<!-- when $scope.myValue is falsy (element is removed) -->
<div ng-if="0"></div>

Wenn ein Element mit ngIf entfernt wird, wird sein Gültigkeitsbereich zerstört und ein neuer Gültigkeitsbereich wird erstellt, wenn das Element wiederhergestellt wird. Der in ngIf erstellte Gültigkeitsbereich erbt mithilfe seines prototypischen Vererbungsbereichs vom übergeordneten Gültigkeitsbereich.

Wenn ngModel innerhalb von ngIf zur Bindung an ein im übergeordneten Bereich definiertes JavaScript-Grundelement verwendet wird, wirken sich Änderungen an der Variablen innerhalb des untergeordneten Bereichs nicht auf den Wert im übergeordneten Bereich aus, z.

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="data">
</div>        

Verwenden Sie ein Objekt, um diese Situation zu umgehen und das Modell im übergeordneten Bereich aus dem untergeordneten Bereich heraus zu aktualisieren:

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>

Oder $parent-Variable, um auf das übergeordnete Bereichsobjekt zu verweisen:

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>

ngShow

Die ngShow-Direktive zeigt oder versteckt das angegebene HTML-Element basierend auf dem Ausdruck, der dem ngShow-Attribut bereitgestellt wird. Das Element wird durch Entfernen oder Hinzufügen der CSS-Klasse ng-hide in das Element ein- oder ausgeblendet. Die .ng-hide-CSS-Klasse ist in AngularJS vordefiniert und setzt den Anzeigestil auf none (mit einem !important-Flag).

<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="1"></div>

<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="0" class="ng-hide"></div>

Wenn der Ausdruck ngShow zu false ausgewertet wird, wird die ng-hide-CSS-Klasse zum class-Attribut des Elements hinzugefügt, wodurch dieses ausgeblendet wird. Bei true wird die CSS-Klasse ng-hide aus dem Element entfernt, sodass das Element nicht verborgen erscheint.

508
AlwaysALearner

Ein interessanter Punkt ist vielleicht der Unterschied zwischen den Prioritäten zwischen beiden. 

Soweit ich das beurteilen kann, hat die ng-if-Direktive eine der höchsten (wenn nicht die höchste) Priorität aller Angular-Direktiven. Was bedeutet: es wird vor allen anderen, niedriger priorisierten Anweisungen FIRST ausgeführt. Die Tatsache, dass es FIRST ausgeführt wird, bedeutet, dass das Element effektiv entfernt wird, bevor irgendwelche inner - Direktiven verarbeitet werden. Oder zumindest: das mache ich daraus.

Ich habe dies in der Benutzeroberfläche, die ich für meinen aktuellen Kunden baue, beobachtet und verwendet. Die gesamte Benutzeroberfläche ist ziemlich voll, und sie hatte ng-show und ng-hide. Um nicht zu sehr ins Detail zu gehen, aber ich baute eine generische Komponente, die mit JSON-Konfiguration verwaltet werden konnte, sodass ich einige Änderungen in der Vorlage vornehmen musste. Es gibt eine ng-Wiederholung, und in der ng-Wiederholung wird eine Tabelle angezeigt, die viele ng-Shows, ng-hides und sogar ng-Schalter enthält. Sie wollten mindestens 50 Wiederholungen in der Liste anzeigen, was dazu führen würde, dass mehr oder weniger 1500-2000 Anweisungen aufgelöst werden. Ich überprüfte den Code und das Java Backend + Custom JS auf der Vorderseite würde etwa 150 ms dauern, um die Daten zu verarbeiten, und Angular kaute 2-3 Sekunden darauf, bevor es angezeigt wurde. Der Kunde hat sich nicht beschwert, aber ich war entsetzt :-) 

Bei meiner Suche bin ich auf die ng-if-Direktive gestoßen. Nun, vielleicht ist es das Beste, darauf hinzuweisen, dass zum Zeitpunkt der Erstellung dieser Benutzeroberfläche kein Ng-If verfügbar war. Da die Funktionen ng-show und ng-hide Funktionen enthielten, die boolean zurückkehrten, konnte ich sie leicht durch ng-if ersetzen. Alle inneren Richtlinien schienen damit nicht mehr bewertet zu werden. Das bedeutete, dass ich auf etwa ein Drittel aller geprüften Anweisungen zurückging. Daher beschleunigte sich die Benutzeroberfläche auf etwa 500 ms - 1 Sekunde Ladezeit. (Ich habe keine Möglichkeit, genaue Sekunden zu bestimmen) 

Bitte beachten Sie: Die Tatsache, dass die Richtlinien nicht bewertet werden, ist eine fundierte Vermutung darüber, was darunter passiert.

Meiner Meinung nach: Wenn das Element auf der Seite vorhanden sein muss (z. B. zum Überprüfen des Elements oder was auch immer), aber einfach ausgeblendet werden soll, verwenden Sie ng-show/ng-hide. In allen anderen Fällen verwenden Sie ng-if. 

92
gjoris

Die ng-if-Direktive entfernt den Inhalt von der Seite und ng-show/ng-hide verwendet die CSS-Eigenschaft display, um den Inhalt auszublenden.

Dies ist nützlich, wenn Sie :first-child und :last-child Pseudo-Selektoren zum Style verwenden möchten.

36
Andrei

@EdSpencer ist korrekt. Wenn Sie viele Elemente haben und ng-if verwenden, um nur die relevanten zu instanziieren, sparen Sie Ressourcen @ CodeHater ist auch einigermaßen korrekt, wenn Sie ein Element sehr oft entfernen und anzeigen, indem Sie es ausblenden Anstatt sie zu entfernen, könnte dies die Leistung verbessern.

Der Hauptanwendungsfall, den ich für ng-if finde, besteht darin, dass ich ein Element sauber validieren und entfernen kann, wenn der Inhalt illegal ist. Ich könnte zum Beispiel auf eine Variable mit dem Namen eines Nullbildes verweisen und dies wird einen Fehler auslösen, aber wenn ich das prüfe, ob es Null ist, ist das alles gut. Wenn ich eine ng-Show machte, würde der Fehler immer noch ausgelöst.

16
wolfdawn

Bei ng-if und ng-show ist zu beachten, dass bei der Verwendung von Formularsteuerelementen die Verwendung von ng-if besser ist, da das Element vollständig aus dem dom entfernt wird. 

Dieser Unterschied ist wichtig, denn wenn Sie ein Eingabefeld mit required="true" erstellen und dann ng-show="false" so einstellen, dass es ausgeblendet wird, gibt Chrome den folgenden Fehler aus, wenn der Benutzer versucht, das Formular zu senden:

An invalid form control with name='' is not focusable.

Der Grund liegt darin, dass das Eingabefeld vorhanden ist und es ist required. Da es jedoch ausgeblendet ist, kann Chrome es nicht fokussieren. Dies kann Ihren Code buchstäblich beschädigen, da dieser Fehler die Skriptausführung stoppt. Also sei vorsichtig!

7
supersan

@Gajus Kuizinas und @CodeHater sind korrekt. Ich gebe hier nur ein Beispiel. Wenn wir mit ng-if arbeiten, werden die gesamten HTML-Elemente aus dem DOM entfernt, wenn der zugewiesene Wert falsch ist. Wenn der zugewiesene Wert true ist, werden die HTML-Elemente im DOM angezeigt. Der Geltungsbereich unterscheidet sich vom übergeordneten Geltungsbereich. Im Falle von ng-show werden die Elemente jedoch nur basierend auf dem zugewiesenen Wert angezeigt und ausgeblendet. Es bleibt aber immer im DOM. Nur die Sichtbarkeit ändert sich entsprechend dem zugewiesenen Wert.

http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview

Ich hoffe, dieses Beispiel wird Ihnen beim Verständnis der Bereiche helfen. Versuchen Sie, falsche Werte für ng-show und ng-if anzugeben, und überprüfen Sie das DOM in der Konsole. Geben Sie die Werte in die Eingabefelder ein und beobachten Sie den Unterschied.

<!DOCTYPE html>

Hallo Plunker!

<input type="text" ng-model="data">
<div ng-show="true">
    <br/>ng-show=true :: <br/><input type="text" ng-model="data">
</div>
<div ng-if="true">
    <br/>ng-if=true :: <br/><input type="text" ng-model="data">
</div> 
{{data}}

5
user3982777

Tatsache, dass die ng-if-Direktive im Gegensatz zu ng-show ihren eigenen Geltungsbereich schafft, führt zu interessanten praktischen Unterschieden:

angular.module('app', []).controller('ctrl', function($scope){
  $scope.delete = function(array, item){
    array.splice(array.indexOf(item), 1);
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='app' ng-controller='ctrl'>
   <h4>ng-if:</h4>
   <ul ng-init='arr1 = [1,2,3]'>
      <li ng-repeat='x in arr1'>
        {{show}}
        <button ng-if='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-if='show' ng-click='delete(arr1, x)'>Yes {{show}}</button>
        <button ng-if='show' ng-click='show=!show'>No</button>
      </li>
   </ul>
   
   <h4>ng-show:</h4>
   <ul ng-init='arr2 = [1,2,3]'>
      <li ng-repeat='x in arr2'>
        {{show}}
        <button ng-show='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-show='show' ng-click='delete(arr2, x)'>Yes {{show}}</button>
        <button ng-show='show' ng-click='show=!show'>No</button>
      </li>
   </ul>
   
   <h4>ng-if with $parent:</h4>
    <ul ng-init='arr3 = [1,2,3]'>
      <li ng-repeat='item in arr3'>
        {{show}}
        <button ng-if='!show' ng-click='$parent.show=!$parent.show'>Delete {{$parent.show}}</button>
        <button ng-if='show' ng-click='delete(arr3, x)'>Yes {{$parent.show}}</button>
        <button ng-if='show' ng-click='$parent.show=!$parent.show'>No</button>
      </li>
   </ul>
</div>

In der ersten Liste wird on-click event, show variable aus innner/own scope geändert, aber ng-if überwacht eine andere Variable aus outer scope mit demselben Namen, sodass die Lösung nicht funktioniert. Bei ng-show haben wir die einzige Variable show, deshalb funktioniert sie. Um den ersten Versuch zu beheben, sollten wir über $parent.show auf show vom übergeordneten/äußeren Bereich verweisen.

2
Slava Utesinov
  1. ng-if if false entfernt Elemente aus DOM. Dies bedeutet, dass alle Ihre Events und Anweisungen, die an diese Elemente angehängt sind, verloren gehen. Wenn Sie beispielsweise ng-click auf eines der untergeordneten Elemente klicken, wird ng-if zu false ausgewertet. Dieses Element wird aus DOM entfernt. Wenn es wahr ist, wird es erneut erstellt.

  2. ng-show/ng-hide entfernt die Elemente nicht aus DOM. Es verwendet CSS-Stile (.ng-hide), um Elemente auszublenden/anzuzeigen. Auf diese Weise gehen Ihre Anweisungen und Anweisungen, die an untergeordnete Elemente angehängt wurden, nicht verloren.

  3. ng-if erstellt einen untergeordneten Bereich, ng-show/ng-hide dagegen nicht.

1
Amay Kulkarni

ngIf nimmt eine Änderung am DOM vor, indem das Element entfernt oder neu erstellt wird. 

Während ngShow wendet CSS-Regeln an, um Dinge auszublenden/anzuzeigen. 

In den meisten Fällen (nicht immer) fasse ich das so zusammen: Wenn Sie eine einmalige Prüfung zum Anzeigen/Verbergen von Dingen benötigen, verwenden Sie ng-if, wenn Sie Dingen basierend auf den Benutzeraktionen anzeigen oder ausblenden müssen den Bildschirm (wie ein Markierungsfeld markiert, dann ein Textfeld anzeigen, deaktiviert, dann ein Textfeld ausblenden usw.), dann ng-show verwenden 

0
curiousBoy

ng-show und ng-hide arbeiten auf die entgegengesetzte Weise. Der Unterschied zwischen ng-hide oder ng-show mit ng-if ist, wenn wir ng-if verwenden, wird das Element im dom erstellt, aber mit ng-hide/ng-show wird das Element vollständig ausgeblendet.

ng-show=true/ng-hide=false:
Element will be displayed

ng-show=false/ng-hide=true:
element will be hidden

ng-if =true
element will be created

ng-if= false
element will be created in the dom. 
0
Prasad Reddy

Beachten Sie, etwas, das mir jetzt passiert ist: Ng-show verbirgt den Inhalt über css, ja, aber es führte zu seltsamen Störungen in Divs, die als Buttons dienen. 

Ich hatte eine Karte mit zwei Knöpfen auf der Unterseite und je nach aktuellem Status wurde eine mit einer dritten, beispielsweise Edit-Schaltfläche mit neuem Eintrag, ausgetauscht. Bei Verwendung von ng-show = false zum Ausblenden des linken (zuerst in der Datei vorhandenen) kam es vor, dass der folgende Button mit dem rechten Rand außerhalb der Karte endete . (Nur hier überprüft, ob es versteckte Überraschungen gibt, die ng-if anstelle von ng-show verwenden)

0
helius