web-dev-qa-db-fra.com

Quand préférer ng-if à 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 cadre du DOM.

Existe-t-il des instructions pour choisir ng-if par rapport à ng-show/ng-hide ou vice-versa?

508
Patrice Chalin

Cela dépend de votre cas d'utilisation, mais pour résumer la différence:

  1. ng-if supprimera les éléments du DOM. Cela signifie que tous vos gestionnaires ou toute autre chose liée à ces éléments seront perdus. Par exemple, si vous liez un gestionnaire de clics à l'un des éléments enfants, lorsque ng-if sera évalué à false, cet élément sera supprimé de DOM et votre gestionnaire de clics ne fonctionnera plus, même après ng-if plus tard. est évalué à true et 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 (note: vous devrez peut-être ajouter vos propres classes). De cette façon, vos gestionnaires attachés aux enfants ne seront pas perdus.
  3. ng-if crée une portée enfant alors que ng-show/ng-hide ne le fait pas.

Les éléments qui ne figurent pas dans le DOM ont moins d’impact sur les performances et votre application Web peut sembler plus rapide lorsque vous utilisez ng-if par rapport à ng-show/ng-hide. D'après 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 un élément de DOM ou non.

695
markovuksanovic

Voir ici pour un CodePen qui montre la différence de fonctionnement de ng-if/ng-show, selon DOM.

@markovuksanovic a bien répondu à la question. Mais j'y arriverais d'un autre point de vue: je toujours utiliserais ng-if et extrairais ces éléments de DOM, à moins que:

  1. pour une raison quelconque, vous avez besoin que les liaisons de données et les $watch- de vos éléments restent actifs tant qu’ils sont invisibles. Les formulaires peuvent être un bon exemple si vous souhaitez pouvoir vérifier la validité des entrées non visibles actuellement afin de déterminer si le formulaire est valide dans sa totalité.
  2. Vous utilisez une logique à états très élaborée avec des gestionnaires d'événements conditionnels, comme mentionné ci-dessus. Ceci dit , si vous vous trouvez en train d'attacher et de détacher manuellement des gestionnaires, de sorte que vous perdez un état important lorsque vous utilisez ng-if, demandez-vous si state serait mieux représenté dans un modèle de données et les gestionnaires appliqués conditionnellement par des directives chaque fois que l'élément est rendu. En d'autres termes, la présence/l'absence de gestionnaires est une forme de données d'état. Obtenez ces données hors 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 très bien écrit. C'est rapide, vu ce que ça fait. Mais ce qu'il fait, c'est tout un tas de magie qui donne une apparence triviale aux choses difficiles (comme la liaison de données bidirectionnelle). Rendre tout cela facile semble entraîner des frais généraux de performance. Vous pourriez être choqué de réaliser combien de centaines, voire de milliers de fois, une fonction de définition est évaluée au cours du cycle $digest sur un bloc de DOM que personne ne regarde même. Et puis vous réalisez 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 de JS sans objet. Mais si vous développez pour le mobile, utiliser ng-if chaque fois que cela est humainement possible devrait être une évidence. JS speed compte toujours pour les processeurs mobiles. Utiliser ng-if est un moyen très simple d'obtenir une optimisation potentiellement significative à un coût très faible.

130
XML

Selon mon expérience:

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

2) ng-if créera/détruira une portée lorsqu’elle sera évaluée comme vraie/fausse. Si vous avez un contrôleur connecté au 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 n'est exécuté qu'une seule fois. Donc, si vous avez un bouton qui bascule entre plusieurs vues, utiliser ng-if et ng-show ferait une énorme différence dans la façon dont vous écrivez le code de votre contrôleur.

53
Yi Z

La réponse n'est pas simple:

Cela dépend des machines cibles (mobile ou de bureau), 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 contre un calcul ... comme avec la plupart des problèmes de performances, la différence peut devenir significative avec éléments répétés (n) comme des listes, en particulier lorsque imbriqué (nxn, ou pire) et aussi quel genre de calculs que vous exécutez à l'intérieur ces éléments:

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

  • ng-if: Si au contraire des éléments risquent de ne pas être affichés (peu nombreux), il suffit de les construire et de les détruire en temps réel, surtout si leur contenu est coûteux à obtenir (calculs/triés/filtrés, images, images générées). Idéal pour les éléments rares ou "à la demande", cela économise de la mémoire car il ne faut pas remplir le DOM, mais cela peut coûter cher en calcul (création/destruction d'éléments) et en bande passante (obtention de contenu distant). Cela dépend également de ce que vous calculez dans la vue (filtrage/tri) par rapport à ce que vous avez déjà dans le modèle (données pré-triées/pré-filtrées).

34
Christophe Roussy

Une note importante:

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

J'ai eu 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 dans une mauvaise portée.)

Donc, pour sauvegarder vos cheveux, utilisez simplement ngShow sauf si vous courez trop lentement.

De toute façon, la différence de performance est à peine perceptible et je ne suis pas encore sûr de savoir qui est en faveur de le faire sans test ...

12
user2173353

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 du ng-if est évaluée à véracité.

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

4
appdroid

ng-si sur ng-include et sur ng-controller aura un impact important sur ng-include, il ne chargera pas le partiel requis et ne sera pas traité, sauf si flag est vrai sur ng-controller, il ne chargera pas le contrôleur sauf si flag true mais le problème est quand un drapeau devient faux dans ng-si il va supprimer de DOM quand flag devient vrai, il rechargera le DOM dans ce cas, ng-show est meilleur, pour une fois, montrer ng-if est meilleur

4
Saad Ahmed