Wann sollte man ng-if gegenüber ng-show / ng-hide bevorzugen?

516

Ich verstehe das ng-showund ng-hidebeeinflusse die Klasse, die für ein Element festgelegt ist, und das ng-ifsteuert, ob ein Element als Teil des DOM gerendert wird.

Gibt es Richtlinien für die Auswahl ng-ifüber ng-show/ ng-hideoder umgekehrt?

Patrice Chalin
quelle
5
Mögliches Duplikat des Unterschieds zwischen ng-if und ng-show / ng-hide
Gajus
1
Nicht im Zusammenhang mit der Dartsprache .
NaXa

Antworten:

703

Hängt von Ihrem Anwendungsfall ab, aber um den Unterschied zusammenzufassen:

  1. ng-ifentfernt Elemente aus DOM. Dies bedeutet, dass alle Ihre Handler oder alles andere, was mit diesen Elementen verbunden ist, verloren gehen. Wenn Sie beispielsweise einen Klick-Handler an eines der untergeordneten Elemente gebunden haben und als ng-iffalsch ausgewertet werden, wird dieses Element aus dem DOM entfernt und Ihr Klick-Handler funktioniert auch nach einer ng-ifspäteren Auswertung als wahr nicht mehr und zeigt das Element an. Sie müssen den Handler wieder anbringen.
  2. ng-show/ng-hideentfernt die Elemente nicht aus DOM. Es verwendet CSS-Stile, um Elemente auszublenden / anzuzeigen (Hinweis: Möglicherweise müssen Sie Ihre eigenen Klassen hinzufügen). Auf diese Weise gehen Ihre Handler, die an Kinder gebunden waren, nicht verloren.
  3. ng-ifErstellt einen untergeordneten Bereich, während ng-show/ng-hidedies nicht der Fall ist

Elemente, die sich nicht im DOM befinden, wirken sich weniger auf die Leistung aus, und Ihre Webanwendung scheint im ng-ifVergleich zu schneller zu sein ng-show/ng-hide. Nach meiner Erfahrung ist der Unterschied vernachlässigbar. Animationen sind möglich, wenn beide ng-show/ng-hideund ng-ifmit Beispielen für beide in der Angular-Dokumentation verwendet werden.

Letztendlich müssen Sie die Frage beantworten, ob Sie ein Element aus dem DOM entfernen können oder nicht.

markovuksanovic
quelle
19
Sie können CSS3-Animationen mit verwenden ng-if. Überprüfen Sie den Absatz Animationen und das Beispiel in den Dokumenten . Auch mit ng-hide/ng-showden CSS-Selektoren gefällt :first-childoder :nth-childfunktioniert es nicht richtig, da auch die versteckten Elemente gezählt werden.
Łukasz Wojciechowski
4
Der Animationsdienst in angle.dart ist relativ neu. Zum Zeitpunkt des Schreibens war dies nicht verfügbar.
Markovuksanovic
44
Ihr erster Punkt ist kein Problem, wenn Sie Anweisungen (wie ng-click) verwenden, um Handler so zu binden, wie Sie es sollten.
Kevin C.
9
Außerdem ng-ifschafft einen neuen Bereich , während ng-showdies nicht tut.
Martin
8
Es sollte auch erwähnt werden, dass das Hinzufügen und Entfernen von Elementen zum DOM bei häufiger Ausführung hohe Leistungskosten verursachen kann.
Kevin C.
130

Sehen Sie hier für eine CodePen, die den Unterschied in wie ng-if / ng-Show arbeiten, DOM-weise demonstriert.

@markovuksanovic hat die Frage gut beantwortet. Aber ich würde es aus einer anderen Perspektive betrachten: Ich würde diese Elemente immer verwenden ng-ifund aus DOM herausholen, es sei denn:

  1. Aus irgendeinem Grund benötigen Sie die Datenbindungen und $watch-es für Ihre Elemente, um aktiv zu bleiben, solange sie unsichtbar sind. Formulare sind hierfür möglicherweise ein guter Fall, wenn Sie die Gültigkeit von Eingaben überprüfen möchten, die derzeit nicht sichtbar sind, um festzustellen, ob das gesamte Formular gültig ist.
  2. Sie verwenden eine wirklich ausgefeilte Stateful-Logik mit bedingten Ereignishandlern, wie oben erwähnt. , Daß das , wenn Sie sich manuell Anbringen und Abnehmen Handler finden, so dass Sie wichtigen Zustand sind zu verlieren , wenn Sie verwenden ng-wenn, fragen Sie sich , ob dieser Zustand wäre besser in einem Datenmodell dargestellt werden, und die Handler angewandt bedingt durch Richtlinien , wann immer Das Element wird gerendert. Anders ausgedrückt ist das Vorhandensein / Fehlen von Handlern eine Form von Statusdaten. Holen Sie sich diese Daten aus dem DOM in ein Modell. Das Vorhandensein / Fehlen der Handler sollte anhand der Daten bestimmt und daher leicht neu erstellt werden können.

Angular ist wirklich gut geschrieben. Es ist schnell, wenn man bedenkt, was es tut. Aber was es tut, ist eine ganze Menge Magie, die schwierige Dinge (wie die bidirektionale Datenbindung) trivial einfach aussehen lässt. Um all diese Dinge einfach aussehen zu lassen, ist ein gewisser Leistungsaufwand erforderlich. Es könnte Sie schockieren, zu erkennen, wie oft hunderte oder tausende Male eine Setterfunktion während des $digestZyklus auf einem Stück DOM ausgewertet wird , das niemand überhaupt betrachtet. Und dann merkt man, dass Dutzende oder Hunderte von unsichtbaren Elementen dasselbe tun ...

Desktops sind möglicherweise leistungsstark genug, um die meisten Probleme mit der JS-Ausführungsgeschwindigkeit zu lösen. Wenn Sie jedoch für Mobilgeräte entwickeln, sollte die Verwendung von ng-if, wann immer dies menschlich möglich ist, ein Kinderspiel sein. Auf mobilen Prozessoren spielt die JS-Geschwindigkeit immer noch eine Rolle. Die Verwendung von ng-if ist ein sehr einfacher Weg, um potenziell signifikante Optimierungen zu sehr, sehr geringen Kosten zu erzielen.

XML
quelle
6
Sehr schöne Ergänzung zur obigen Antwort. Gegeben mit einem guten Kontext, der auch bei der Entscheidungsfindung hilft. Vielen Dank.
Sean
1
ng-showkann nützlich sein, wenn Sie beispielsweise Registerkarten mit viel Inhalt haben, dessen Rendern einige Zeit in Anspruch nimmt. Nach dem ersten Rendern erfolgt das Wechseln zwischen Registerkarten sofort, während ng-ifein erneutes Rendern, Binden von Ereignissen usw. erforderlich ist. Der Nachteil besteht darin, dass Uhren erstellt werden, die im Hintergrund ausgeführt werden. Angular braucht dringendng-ifshowwatch
vornehmste
53

Meiner Erfahrung nach:

1) Wenn Ihre Seite einen Schalter hat, der ng-if / ng-show verwendet, um etwas anzuzeigen / auszublenden, verursacht ng-if eine größere Verzögerung des Browsers (langsamer). Beispiel: Wenn Sie eine Schaltfläche zum Umschalten zwischen zwei Ansichten haben, scheint ng-show schneller zu sein.

2) ng-if erstellt / zerstört den Bereich, wenn es als wahr / falsch ausgewertet wird. Wenn Sie einen Controller an das ng-if angeschlossen haben, wird dieser Controller-Code jedes Mal ausgeführt, wenn das ng-if den Wert true hat. Wenn Sie ng-show verwenden, wird der Controller-Code nur einmal ausgeführt. Wenn Sie also eine Schaltfläche haben, die zwischen mehreren Ansichten umschaltet, würde die Verwendung von ng-if und ng-show einen großen Unterschied beim Schreiben Ihres Controller-Codes bewirken.

Yi Z.
quelle
5
Das ist eine riesige Wahrheit! ng-if macht Ihr Frontend nicht unbedingt schneller. Es hängt von Ihren Bedürfnissen ab. Eigentlich könnte es umgekehrt sein, wenn Sie in der falschen Situation verwenden.
Thiago C. S Ventura
1
Aber meiner Meinung nach wird ng-if nicht auf DOM gerendert, so dass es im Vergleich zu ng-show / hide schnell ist. bin ich falsch pls lassen Sie mich an diesem Punkt korrigieren.
Pardeep Jain
1
ng-if wäre schneller, wenn es als false ausgewertet würde, da, wie Sie sagen, nichts in das DOM eingefügt werden muss. Wenn dies jedoch zutrifft, müssen Sie das - möglicherweise recht komplizierte - Element in das DOM einfügen.
Mawg sagt, Monica
"2) ng-if erstellt / zerstört den Bereich, wenn er als wahr / falsch ausgewertet wird. Wenn Sie einen Controller an ng-if angeschlossen haben, wird dieser Controller-Code jedes Mal ausgeführt, wenn"
The Red Pea
35

Die Antwort ist nicht einfach:

Es hängt von den Zielcomputern ab (mobil oder Desktop), es hängt von der Art Ihrer Daten, dem Browser, dem Betriebssystem, der Hardware ab, auf der es ausgeführt wird ... Sie müssen ein Benchmarking durchführen, wenn Sie es wirklich wissen möchten.

Es handelt sich meistens um ein Speicher- oder Berechnungsproblem. Wie bei den meisten Leistungsproblemen kann der Unterschied bei wiederholten Elementen (n) wie Listen erheblich werden , insbesondere wenn sie verschachtelt sind (nxn oder schlechter) und auch, welche Art von Berechnungen Sie in diesen Elementen ausführen ::

  • ng-show : Wenn diese optionalen Elemente häufig vorhanden (dicht) sind, wie beispielsweise in 90% der Fälle, ist es möglicherweise schneller, sie bereit zu halten und nur anzuzeigen / auszublenden, insbesondere wenn ihr Inhalt billig ist (nur einfacher Text, nichts zu berechnen oder zu laden). Dies verbraucht Speicher, da es das DOM mit versteckten Elementen füllt, aber nur etwas anzuzeigen / auszublenden, was bereits vorhanden ist, ist wahrscheinlich eine billige Operation für den Browser.

  • ng-if : Wenn im Gegenteil Elemente wahrscheinlich nicht angezeigt werden (spärlich), erstellen Sie sie einfach und zerstören Sie sie in Echtzeit, insbesondere wenn ihr Inhalt teuer zu beschaffen ist (Berechnungen / sortiert / gefiltert, Bilder, generierte Bilder). Dies ist ideal für seltene oder On-Demand-Elemente. Es spart Speicherplatz, da das DOM nicht gefüllt wird, kann jedoch viel Rechenaufwand (Erstellen / Zerstören von Elementen) und Bandbreite (Abrufen von Remote-Inhalten) kosten. Dies hängt auch davon ab, wie viel Sie in der Ansicht berechnen (Filtern / Sortieren) und was Sie bereits im Modell haben (vorsortierte / vorgefilterte Daten).

Christophe Roussy
quelle
2
Andere Antworten für technische Fakten. Dieser für Weisheit. Sie haben eindeutig nicht triviale Angular-Apps erstellt, Sir! +1
vornehmster
Dieses Problem geht über den Winkel hinaus, es ist ein grundlegendes Problem in der Informatik, es gibt einen Punkt, von dem aus eine Methode effizienter ist als die andere. Normalerweise kann dies durch ein Benchmarking festgestellt werden. Sie können also je nach Anzahl der Elemente
Christophe Roussy
12

Ein wichtiger Hinweis:

ngIf (im Gegensatz zu ngShow) erstellt normalerweise untergeordnete Bereiche, die zu unerwarteten Ergebnissen führen können.

Ich hatte ein Problem damit und ich habe VIEL Zeit damit verbracht herauszufinden, was los war.

(Meine Direktive schrieb ihre Modellwerte in den falschen Bereich.)

Um Ihre Haare zu schonen, verwenden Sie einfach ngShow, es sei denn, Sie laufen zu langsam.

Der Leistungsunterschied ist ohnehin kaum spürbar und ich bin mir noch nicht sicher, wer es ohne Test bevorzugt ...

user2173353
quelle
8
Die Verwendung $parent.scopevarvon Datenbindungen innerhalb eines ngIf behebt Probleme mit untergeordneten
meconroy
2
Dies ist nicht ganz richtig (das heißt, der ursprüngliche Kommentar von @ user2173353). Wenn Sie sich an gute Praktiken halten, werden Sie keine Probleme bekommen. Das ist eine ziemlich grundlegende Regel: "Wenn es keinen Punkt gibt, machst du es falsch". Hier finden Sie eine Demo der Funktionsweise: bit.ly/1SPv4wL . Eine weitere gute Referenz (siehe Fehler Nr. 2): bit.ly/1QfFeWd > (Meine Direktive schrieb ihre Modellwerte in den falschen Bereich.) Dies ist das Ergebnis der Nichteinhaltung der obigen Vorgehensweise.
piotr.d
1
@ piotr.d Sie haben Recht, aber darauf muss sich ein Anfänger möglicherweise nicht konzentrieren, und es gibt eine weitere bewährte Methode, die besagt, dass es besser ist, Leistungsverbesserungen für das Ende zu belassen (insbesondere Leistungsverbesserungen, die in der Realität möglicherweise keine Verbesserungen darstellen ). Ich habe ngIfüberall Leute gesehen, die glaubten, dass dies die Leistung verbessern wird. Dies ist einfach nicht wahr und man kann nicht sagen, welches am besten ist, ngIfoder ngShowohne einen Test oder eine gründliche Analyse im speziellen Fall. Daher empfehle ich immer noch zu vergessen ngIf, bis man eine schlechte Leistung sieht oder weiß, was er tut
user2173353
2
Guter Punkt. Die Verwendung von controllerAs macht dies jedoch zu einem Problem. Siehe zum Beispiel John Papas Übernahme von controllerAs und vm .
Jsruok
4

ng-if auf ng-include und auf ng-controller hat einen großen Einfluss auf ng-include. Es lädt nicht den erforderlichen Teil und verarbeitet nicht, es sei denn, das Flag ist wahr auf ng-controller. Es lädt den Controller nicht, es sei denn, das Flag ist true, aber das Problem ist, wenn ein Flag in ng falsch wird. Wenn es aus dem DOM entfernt wird, wenn das Flag wieder true wird, wird das DOM neu geladen. In diesem Fall ist ng-show besser, einmal zeigt ng-if besser

Saad Ahmed
quelle
4

Wenn Sie ng-show or ng-hideden Inhalt verwenden (z. B. Miniaturansichten vom Server), wird dieser unabhängig vom Wert des Ausdrucks geladen, jedoch basierend auf dem Wert des Ausdrucks angezeigt.

Wenn Sie ng-ifden Inhalt verwenden, wird er nur geladen, wenn der Ausdruck des ng-if als wahr ausgewertet wird.

Die Verwendung von ng-if ist eine gute Idee in einer Situation, in der Sie Daten oder Bilder vom Server laden und diese nur in Abhängigkeit von der Benutzerinteraktion anzeigen. Auf diese Weise wird das Laden Ihrer Seite nicht durch unnötige neue intensive Aufgaben blockiert.

Appdroid
quelle
Dies ist besonders nützlich, da die meisten Browser Bilder laden, selbst wenn das CSS ihre DOM-Container verbirgt. Sie suchen normalerweise nur nach dem srcAttribut des imgTags, wenn es vorhanden ist, wird es geladen!
Christophe Roussy