Ich versuche den Unterschied zwischen ng-if
und ng-show
/ zu verstehen ng-hide
, aber sie sehen für mich gleich aus.
Gibt es einen Unterschied, den ich beachten sollte, wenn ich mich für den einen oder anderen entscheide?
Ich versuche den Unterschied zwischen ng-if
und ng-show
/ zu verstehen ng-hide
, aber sie sehen für mich gleich aus.
Gibt es einen Unterschied, den ich beachten sollte, wenn ich mich für den einen oder anderen entscheide?
Antworten:
Die ngIf
Direktive entfernt oder erstellt einen Teil des DOM-Baums basierend auf einem Ausdruck neu. Wenn der Ausdruck, der zugewiesen wird, ngIf
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 mithilfe ngIf
seines Bereichs entfernt wird, wird es zerstört und ein neuer Bereich wird erstellt, wenn das Element wiederhergestellt wird. Der innerhalb ngIf
von erstellte Bereich erbt mithilfe der prototypischen Vererbung von seinem übergeordneten Bereich.
Wenn ngModel
innerhalb verwendet wird ngIf
, um an ein im übergeordneten Bereich definiertes JavaScript-Grundelement zu binden, wirken sich Änderungen an der Variablen im untergeordneten Bereich 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 innerhalb des untergeordneten Bereichs 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>
Die ngShow
Direktive zeigt oder verbirgt das angegebene HTML-Element basierend auf dem Ausdruck, der für das ngShow
Attribut bereitgestellt wird. Das Element wird angezeigt oder ausgeblendet, indem die ng-hide
CSS-Klasse entfernt oder dem Element hinzugefügt wird. Die .ng-hide
CSS-Klasse ist in AngularJS vordefiniert und setzt den Anzeigestil auf none (mithilfe eines !important
Flags).
<!-- 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 ngShow
Ausdruck ausgewertet wird, false
wird die ng-hide
CSS-Klasse dem class
Attribut des Elements hinzugefügt, wodurch es ausgeblendet wird. Wenn true
die ng-hide
CSS-Klasse aus dem Element entfernt wird, wird das Element nicht ausgeblendet angezeigt.
data.input
es funktioniert ... aber data
allein im Modell funktioniert es nicht. @ CodeHater
ngIf
erstellt einen neuen Bereich. Wenn Sie also das obige Beispiel über dem verschachtelten betrachten ngModel
, wird ein neues data
Modell erstellt, obwohl im übergeordneten Bereich ein Modell mit demselben Namen vorhanden ist. Wenn Sie jedoch eine Punktnotation verwenden, lässt JS die Prototypenkette des Oszilloskops nachschlagen. Wenn der Wert im aktuellen Bereich nicht gefunden wird, wird versucht, ihn im übergeordneten Bereich usw. zu suchen. Nur wenige andere Richtlinien, die einen anderen Geltungsbereich schaffen, sind ngInclude
, ngRepeat
. Hoffe es ist jetzt klar. :)
Vielleicht ist ein interessanter Punkt 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. Das heißt: Es wird ZUERST vor allen anderen Direktiven mit niedrigerer Priorität ausgeführt. Die Tatsache, dass es ZUERST ausgeführt wird, bedeutet, dass das Element effektiv entfernt wird, bevor innere Anweisungen verarbeitet werden. Oder zumindest: das mache ich daraus.
Ich habe dies beobachtet und in der Benutzeroberfläche verwendet, die ich für meinen aktuellen Kunden erstelle. Die gesamte Benutzeroberfläche ist ziemlich voll und es gab überall ng-show und ng-hide. Um nicht zu sehr ins Detail zu gehen, habe ich eine generische Komponente erstellt, die mit der JSON-Konfiguration verwaltet werden kann, sodass ich einige Änderungen in der Vorlage vornehmen musste. Es ist eine ng-Wiederholung vorhanden, und innerhalb der ng-Wiederholung wird eine Tabelle angezeigt, in der viele ng-Shows, ng-Häute und sogar ng-Schalter vorhanden sind. Sie wollten mindestens 50 Wiederholungen in der Liste anzeigen, was dazu führen würde, dass mehr oder weniger 1500-2000 Anweisungen gelöst werden müssten. Ich habe den Code überprüft, und das Java-Backend + benutzerdefiniertes JS auf der Vorderseite würde ungefähr 150 ms dauern, um die Daten zu verarbeiten, und dann würde Angular 2-3 Sekunden darauf kauen, bevor es angezeigt wird. Der Kunde hat sich nicht beschwert, aber ich war entsetzt :-)
Bei meiner Suche bin ich auf die ng-if-Direktive gestoßen. Nun ist es vielleicht am besten darauf hinzuweisen, dass zum Zeitpunkt der Konzeption dieser Benutzeroberfläche kein ng-if verfügbar war. Da ng-show und ng-hide Funktionen enthielten, die Boolesche Werte zurückgaben, konnte ich sie alle leicht durch ng-if ersetzen. Auf diese Weise schienen nicht alle inneren Richtlinien mehr bewertet zu werden. Das bedeutete, dass ich auf ungefähr ein Drittel aller evaluierten Direktiven zurückfiel und die Benutzeroberfläche auf ungefähr 500 ms beschleunigte - 1 Sekunde Ladezeit. (Ich habe keine Möglichkeit, genaue Sekunden zu bestimmen)
Beachten Sie: Die Tatsache, dass die Richtlinien nicht bewertet werden, ist eine fundierte Vermutung darüber, was darunter geschieht.
Meiner Meinung nach: Wenn das Element auf der Seite vorhanden sein muss (dh 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.
Die ng-if
Direktive entfernt den Inhalt von der Seite und ng-show/ng-hide
verwendet die CSS- display
Eigenschaft, um den Inhalt auszublenden.
Dies ist nützlich, wenn Sie verwenden möchten , :first-child
und :last-child
zu Stilselektoren Pseudo.
:first-child
und :last-child
developer.mozilla.org/en-US/docs/Web/CSS/:first-child developer.mozilla.org/en-US/docs/Web/CSS/:last-child
@ EdSpencer ist korrekt. Wenn Sie viele Elemente haben und ng-if verwenden, um nur die relevanten zu instanziieren, sparen Sie Ressourcen. @CodeHater ist auch etwas korrekt, wenn Sie ein Element sehr oft entfernen und anzeigen möchten. Wenn Sie es ausblenden, anstatt es zu entfernen, kann dies die Leistung verbessern.
Der Hauptanwendungsfall, den ich für ng-if finde, ist, dass ich damit ein Element sauber validieren und entfernen kann, wenn der Inhalt illegal ist. Zum Beispiel könnte ich auf eine Variable für den Nullbildnamen verweisen, und das wird einen Fehler auslösen, aber wenn ich ng-if und prüfe, ob es null ist, ist alles gut. Wenn ich eine ng-Show machen würde, würde der Fehler immer noch ausgelöst.
Eine wichtige Sache, die Sie bei ng-if und ng-show beachten sollten, ist, dass die Verwendung von Formularsteuerelementen besser ist, ng-if
da das Element vollständig aus dem Dom entfernt wird.
Dieser Unterschied ist wichtig, denn wenn Sie ein Eingabefeld mit erstellen required="true"
und dann festlegen ng-show="false"
, 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 dafür ist, dass das Eingabefeld vorhanden ist und es ist, required
aber da es versteckt ist, kann sich Chrome nicht darauf konzentrieren. Dies kann Ihren Code buchstäblich beschädigen, da dieser Fehler die Skriptausführung anhält. Also sei vorsichtig!
@Gajus Kuizinas und @CodeHater sind korrekt. Hier gebe ich nur ein Beispiel. Während wir mit ng-if arbeiten und der zugewiesene Wert falsch ist, werden die gesamten HTML-Elemente aus dem DOM entfernt. Wenn der zugewiesene Wert true ist, werden die HTML-Elemente im DOM angezeigt. Der Umfang unterscheidet sich vom übergeordneten Bereich. Im Falle von ng-show werden jedoch nur die Elemente basierend auf dem zugewiesenen Wert angezeigt und ausgeblendet. Aber es bleibt immer im DOM. Nur die Sichtbarkeit ändert sich gemäß dem zugewiesenen Wert.
http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview
Ich hoffe, dieses Beispiel hilft Ihnen beim Verständnis der Bereiche. Versuchen Sie, ng-show und ng-if falsche Werte zu geben, und überprüfen Sie das DOM in der Konsole. Geben Sie die Werte in die Eingabefelder ein und beobachten Sie den Unterschied.
<!DOCTYPE html>
<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}}
Tatsache, dass diese ng-if
Richtlinie im Gegensatz zu ng-show
ihrem eigenen Geltungsbereich einen interessanten praktischen Unterschied schafft:
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
Ereignis, show
Variable aus dem inneren / eigenen Bereich geändert, es wird jedoch ng-if
eine andere Variable aus dem äußeren Bereich mit demselben Namen überwacht , sodass die Lösung nicht funktioniert. Wenn ng-show
wir die einzige show
Variable haben, funktioniert sie deshalb. Um den ersten Versuch zu korrigieren, sollten wir über auf den show
übergeordneten / äußeren Bereich verweisen $parent.show
.
ng-if if false entfernt Elemente aus dem DOM. Dies bedeutet, dass alle Ihre Ereignisse und Anweisungen, die diesen Elementen zugeordnet sind, verloren gehen. Wenn Sie beispielsweise mit der rechten Maustaste auf eines der untergeordneten Elemente klicken und ng-if als false auswertet, wird dieses Element aus dem DOM entfernt und erneut erstellt, wenn es wahr ist.
ng-show / ng-hide entfernt die Elemente nicht aus dem DOM. Es verwendet CSS-Stile (.ng-hide), um Elemente auszublenden / anzuzeigen. Auf diese Weise gehen Ihre Ereignisse und Anweisungen, die an untergeordnete Elemente angehängt wurden, nicht verloren.
ng-if erstellt einen untergeordneten Bereich, ng-show / ng-hide nicht.
ng-show und ng-hide arbeiten in umgekehrter Weise. Der Unterschied zwischen ng-hide oder ng-show mit ng-if besteht jedoch darin, dass bei Verwendung von ng-if das Element im dom erstellt wird, das Element ng-hide / ng-show jedoch vollständig ausgeblendet wird.
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.
Zu beachten, eine Sache, die mir jetzt passiert ist: ng-show verbirgt den Inhalt über CSS, ja, aber es führte zu seltsamen Störungen in Divs, die angeblich Schaltflächen sind.
Ich hatte eine Karte mit zwei Knöpfen auf der Unterseite und je nach aktuellem Zustand wird einer gegen einen dritten ausgetauscht, Beispielbearbeitungsknopf mit neuem Eintrag. Wenn Sie ng-show = false verwenden, um die linke (zuerst in der Datei vorhandene) auszublenden, kam es vor, dass die folgende Schaltfläche mit dem rechten Rand außerhalb der Karte endete. ng-if behebt das, indem der Code überhaupt nicht enthalten ist. (Nur hier überprüft, ob es einige versteckte Überraschungen gibt, wenn ng-if anstelle von ng-show verwendet wird.)
ngIf nimmt eine Manipulation am DOM vor, indem das Element entfernt oder neu erstellt wird.
Während ngShow eine CSS-Regel anwendet, um Dinge zu verbergen / anzuzeigen .
In den meisten Fällen (nicht immer) würde ich dies wie folgt zusammenfassen: Wenn Sie eine einmalige Überprüfung zum Ein- / Ausblenden von Dingen ng-if
benötigen , verwenden Sie , wenn Sie Dinge basierend auf den Benutzeraktionen auf dem Bildschirm anzeigen / ausblenden müssen (wie aktiviert) ein Kontrollkästchen dann Textfeld anzeigen, deaktiviert, dann Textfeld ausblenden usw.), dann verwendenng-show
Ein interessanter Unterschied zwischen ng-if und ng-show ist:
SICHERHEIT
Im ng-if-Block vorhandene DOM-Elemente werden im Falle ihres Werts als false nicht gerendert
Wo wie im Fall von ng-show, kann der Benutzer das Inspect Element-Fenster öffnen und seinen Wert auf TRUE setzen.
Und mit einem Whoop werden ganze Inhalte angezeigt, die versteckt werden sollten, was eine Sicherheitsverletzung darstellt. :) :)
ng-if
dem Modell, das von hinzugefügt wurdeng-model
, ist es nicht mehr vorhanden.