Quand privilégier ng-if vs ng-show / ng-hide?

Je comprends que ng-show et ng-hide affectent la classe définie sur un élément et que ng-if contrôle si un élément est rendu dans le DOM.

Existe-t-il des directives sur le choix de ng-if sur ng-show / ng-hide ou vice-versa?

Dépend de votre cas d’utilisation mais pour résumer la différence:

  1. ng-if va supprimer des éléments de DOM. Cela signifie que tous vos gestionnaires ou tout autre élément attaché à ces éléments seront perdus. Par exemple, si vous avez lié un gestionnaire de clic à l’un des éléments enfants, lorsque ng-if évalué à false, cet élément sera supprimé de DOM et votre gestionnaire de clic ne fonctionnera plus, même ng-if affiche l’élément. Vous devrez rattacher le gestionnaire.
  2. ng-show/ng-hide ne supprime pas les éléments de DOM. Il utilise les styles CSS pour masquer / afficher les éléments (remarque: vous devrez peut-être append vos propres classes). De cette façon, vos gestionnaires attachés aux enfants ne seront pas perdus.
  3. ng-if crée une étendue enfant alors que ng-show/ng-hide ne le fait pas

Les éléments qui ne sont pas dans le DOM ont moins d’impact sur les performances et votre application Web peut sembler plus rapide lorsque vous utilisez ng-if ng-show/ng-hide . Dans mon expérience, la différence est négligeable. Les animations sont possibles avec ng-show/ng-hide et ng-if , avec des exemples pour les deux dans la documentation Angular.

En fin de compte, la question à laquelle vous devez répondre est de savoir si vous pouvez supprimer ou non l’élément DOM?

Voir ici pour un CodePen qui démontre la différence dans le fonctionnement de ng-if / ng-show, en termes de DOM.

@markovuksanovic a bien répondu à la question. Mais j’y reviendrais d’un autre sharepoint vue: j’utiliserais toujours ng-if et sortirais ces éléments de DOM, à moins que:

  1. Pour une raison quelconque, vous avez besoin des liaisons de données et de $watch -es sur vos éléments pour restr actifs tant qu’ils sont invisibles. Les formulaires peuvent être un bon exemple si vous voulez pouvoir vérifier la validité des entrées qui ne sont pas visibles actuellement, afin de déterminer si le formulaire entier est valide.
  2. Vous utilisez une logique dynamic très élaborée avec des gestionnaires d’événements conditionnels, comme mentionné ci-dessus. Cela dit , si vous vous connectez et détachez manuellement des gestionnaires, de sorte que vous perdez des états importants lorsque vous utilisez ng-if, demandez-vous si cet état serait mieux représenté dans un modèle de données et les gestionnaires appliqués l’élément est rendu. En d’autres termes, la présence / absence de gestionnaires est une forme de données d’état. Sortez ces données du DOM et dans un modèle. La présence / absence des gestionnaires doit être déterminée par les données et donc facile à recréer.

Angular est vraiment bien écrit. C’est rapide, compte tenu de ce qu’il fait. Mais ce qu’il fait, c’est tout un tas de magie qui rend les choses difficiles (comme la liaison de données bidirectionnelle) très simples. Rendre toutes ces choses faciles implique des coûts de fonctionnement. Vous pourriez être choqué de voir combien de centaines, voire de milliers de fois, une fonction setter est évaluée pendant le cycle $digest sur un morceau de DOM que personne ne regarde. Et puis vous vous rendez compte que vous avez des dizaines ou des centaines d’éléments invisibles qui font tous la même chose …

Les ordinateurs de bureau peuvent en effet être suffisamment puissants pour rendre la plupart des problèmes de vitesse d’exécution JS infondés. Mais si vous développez pour mobile, utiliser ng-if à chaque fois que cela est humainement possible devrait être une évidence. La vitesse JS est toujours importante pour les processeurs mobiles. L’utilisation de ng-if est un moyen très facile d’obtenir une optimisation potentiellement significative à très très faible coût.

Selon mon expérience:

1) Si votre page a une bascule qui utilise ng-if / ng-show pour afficher / masquer quelque chose, ng-if provoque plus de retard dans le navigateur (plus lent). Par exemple: si vous utilisez un bouton pour basculer entre deux vues, ng-show semble être plus rapide.

2) ng-if va créer / détruire la scope quand elle est évaluée à true / false. Si vous avez un contrôleur attaché à ng-if, ce code de contrôleur sera exécuté chaque fois que ng-if est évalué à true. Si vous utilisez ng-show, le code du contrôleur est exécuté une seule fois. Donc, si vous avez un bouton permettant de basculer entre plusieurs vues, l’utilisation de ng-if et de ng-show ferait une énorme différence dans la manière d’écrire votre code de contrôleur.

La réponse n’est pas simple:

Cela dépend des machines cibles (mobile contre bureau), cela dépend de la nature de vos données, du navigateur, du système d’exploitation, du matériel sur lequel il s’exécute … vous devrez évaluer si vous voulez vraiment savoir.

C’est surtout un problème de mémoire ou de calcul … comme avec la plupart des problèmes de performances, la différence peut devenir importante avec des éléments répétés (n) comme les listes, surtout quand ils sont nesteds (nxn ou pire). :

  • ng-show : Si ces éléments optionnels sont souvent présents (dense), comme par exemple 90% du temps, il peut être plus rapide de les préparer et de les afficher / masquer, surtout si leur contenu est bon marché (juste du texte, rien pour calculer ou charger). Cela consum de la mémoire car elle remplit le DOM avec des éléments cachés, mais il suffit de montrer / cacher quelque chose qui existe déjà est susceptible d’être une opération peu coûteuse pour le navigateur.

  • ng-if : Si au contraire les éléments ne sont pas susceptibles d’être affichés (simplement), il suffit de les construire et de les détruire en temps réel, surtout si leur contenu est coûteux à obtenir (calculs / sortingés / filtrés, images, images générées). C’est idéal pour les éléments rares ou «à la demande», cela économise de la mémoire en termes de ne pas remplir le DOM mais peut coûter beaucoup de calcul (créer / détruire des éléments) et de la bande passante (obtenir du contenu distant). Cela dépend aussi de ce que vous calculez dans la vue (filtrage / sorting) par rapport à ce que vous avez déjà dans le modèle (données pré-sortingées / pré-filtrées).

Une note importante:

ngIf (contrairement à ngShow) crée généralement des scopes enfants pouvant produire des résultats inattendus.

J’avais un problème lié à cela et j’ai passé beaucoup de temps à comprendre ce qui se passait.

(Ma directive écrivait ses valeurs de modèle sur la mauvaise scope.)

Donc, pour enregistrer vos cheveux, utilisez simplement ngShow à moins que vous ne couriez trop lentement.

La différence de performance est à peine perceptible de toute façon et je ne suis pas encore sûr de qui est la faveur sans un test …

ng-if sur ng-include et ng-controller aura un gros impact sur ng-include, il ne chargera pas le partiel requirejs et ne traitera pas à moins que flag ne soit vrai sur ng-controller, il ne chargera pas le contrôleur à moins que flag true mais le problème est quand un drapeau devient faux dans ng -si il va supprimer de DOM quand l’indicateur devient vrai il rechargera le DOM dans ce cas ng-show est mieux, pour une fois show ng-if est mieux

Si vous utilisez ng-show or ng-hide le contenu (par exemple, les vignettes du serveur) sera chargé quelle que soit la valeur de l’expression, mais sera affiché en fonction de la valeur de l’expression.

Si vous utilisez ng-if le contenu ne sera chargé que si l’expression de ng-if est évaluée à truthy.

Utiliser ng-if est une bonne idée dans une situation où vous allez charger des données ou des images à partir du serveur et les afficher uniquement en fonction de l’interaction des utilisateurs. De cette façon, votre chargement de page ne sera pas bloqué par des tâches inutiles.