AngularJS: Pourquoi ng-bind est meilleur que {{}} en angulaire?

401

J'étais dans l'une des présentations angulaires et l'une des personnes à la réunion mentionnée ng-bindvaut mieux que {{}}contraignant.

L'une des raisons, ng-bindmettre la variable dans la liste de surveillance et seulement lorsqu'il y a un changement de modèle, les données sont poussées à afficher, d'autre part, {{}}vont interpoler l'expression à chaque fois (je suppose que c'est le cycle angulaire) et pousser même si la valeur a changé ou non.

Il est également dit que si vous n'avez pas beaucoup de données à l'écran, vous pouvez les utiliser {{}}et que le problème de performances ne sera pas visible. Quelqu'un peut-il faire la lumière sur cette question pour moi?

Nair
la source
3
Pourriez-vous s'il vous plaît vérifier, si ma réponse est la meilleure
Konstantin Krass
{{}} à mon avis n'est pas pratique, le spectateur verra votre tag avant que les données ne soient complètement chargées. Je me demande si l'équipe Angular ne pourra jamais résoudre ce problème.
Jerry Liang
2
@Blazemonger: Ne pouvez-vous pas simplement inclure l'attribut ng-cloak pour empêcher l'affichage temporaire des modèles?
supershnee

Réponses:

322

Si vous n'utilisez pas ng-bind, à la place quelque chose comme ceci:

<div>
  Hello, {{user.name}}
</div>

vous pouvez voir le réel Hello, {{user.name}}pendant une seconde avant la user.namerésolution (avant le chargement des données)

Vous pourriez faire quelque chose comme ça

<div>
  Hello, <span ng-bind="user.name"></span>
</div>

si c'est un problème pour vous.

Une autre solution consiste à utiliser ng-cloak.

principe holographique
la source
3
D'après ce que vous dites, aucune performance n'est atteinte si nous utilisons {{}}? On m'a dit que si vous utilisez {{}} à chaque fois, cela entraînera une inerpolation et générera le résultat même si le modèle ne change pas.
Nair
4
Et comment utiliser ng-bind si je ne veux pas envelopper user.name dans la balise span? Si j'utilise des accolades, j'obtiendrai un nom propre, sans balises html
Victor
5
@KevinMeredith il apparaît comme ça quand le HTML est chargé, mais pas angulaire (pas encore). N'oubliez pas qu'il s'agit de modèles côté client dont nous parlons. Toute l'interpolation doit être effectuée dans le navigateur qui charge l'application. Habituellement, les charges angulaires sont suffisamment rapides pour ne pas être visibles, mais dans certains cas, cela devient un problème. Donc, a ng-cloakété inventé pour réparer ce problème.
principe holographique
17
pour moi, ce n'est pas la réponse à la question, pourquoi ngBind est mieux. C'est juste comment utiliser ngBind au lieu de l'annotation {{}} et une référence à ngCloak.
Konstantin Krass
4
@Victor, ng-bind-templatevous pouvez également combiner les deux approches: ng-bind-template="Hello, {{user.name}}"ici, la liaison offre toujours une amélioration des performances et n'introduit plus d'imbrication
détendez-vous
543

Visibilité:

Pendant que votre angularjs démarre, l'utilisateur peut voir vos crochets placés dans le html. Cela peut être géré avec ng-cloak. Mais pour moi, c'est une solution de contournement, que je n'ai pas besoin d'utiliser, si j'utilise ng-bind.


Performance:

Le {{}}est beaucoup plus lent .

Il ng-binds'agit d'une directive qui placera un observateur sur la variable transmise. Donc, ng-bindcela ne s'applique que lorsque la valeur transmise change réellement .

Les supports en revanche seront cochés et rafraîchis à chaque fois $digest , même si ce n'est pas nécessaire .


Je suis en train de créer une grande application d'une seule page (~ 500 liaisons par vue). Passer de {{}} à strict ng-bindnous a permis d'économiser environ 20% à chaque fois scope.$digest.


Suggestion :

Si vous utilisez un module de traduction tel que angular-translate , préférez toujours les directives avant l'annotation des crochets.

{{'WELCOME'|translate}} => <span ng-translate="WELCOME"></span>

Si vous avez besoin d'une fonction de filtre, optez plutôt pour une directive, qui utilise en fait simplement votre filtre personnalisé. Documentation pour le service $ filter


MISE À JOUR 28.11.2014 (mais peut-être hors du sujet):

Dans Angular 1.3x, la bindoncefonctionnalité a été introduite. Par conséquent, vous pouvez lier la valeur d'une expression / d'un attribut une fois (sera lié lorsque! = 'Non défini').

Ceci est utile lorsque vous ne vous attendez pas à ce que votre liaison change.

Utilisation: Placez ::avant votre reliure:

<ul>  
  <li ng-repeat="item in ::items">{{item}}</li>
</ul>  
<a-directive name="::item">
<span data-ng-bind="::value"></span>

Exemple:

ng-repeatpour afficher des données dans le tableau, avec plusieurs liaisons par ligne. Liaisons de traduction, sorties de filtre, qui s'exécutent dans chaque résumé de portée.

Konstantin Krass
la source
32
c'est une meilleure réponse
NimChimpsky
13
D'après ce que je peux dire de la source (à partir du 2014-11-24), l'interpolation bouclée est gérée comme une directive (voir addTextInterpolateDirective () dans ng / compile.js). Il utilise également $ watch pour que le DOM ne soit pas touché si le texte ne change pas, il ne le "vérifie pas et ne le rafraîchit pas" à chaque $ digest comme vous le prétendez. Ce qui est fait sur chaque $ digest cependant, c'est que la chaîne de résultat interpolée est calculée. Il n'est simplement pas affecté au nœud de texte, sauf s'il change.
Matti Virkkunen
6
J'ai écrit un test de performance pour une évaluation interne. Il avait 2000 entrées dans une répétition ng et affichait 2 attributs dans l'objet, donc des liaisons 2000x2. Les liaisons diffèrent par: La première liaison n'était que la liaison dans une plage. Les secondes avaient une reliure et du HTML simple. Résultat: ng-bind était plus rapide d'environ 20% par portée. Sans vérifier le code, il semble que le html ordinaire supplémentaire avec une expression bouclée dans un élément html prend encore plus de temps.
Konstantin Krass
2
Je veux juste souligner que selon les tests ici: jsperf.com/angular-bind-vs-brackets semble montrer que les crochets sont plus rapides que bind. (Remarque: les barres sont des opérations par seconde, donc plus c'est mieux). Et comme le soulignent les commentaires précédents, leurs mécanismes de surveillance sont finalement identiques.
Warren
1
Parce que vous ne fournissez aucune source, je vous en donne une: ng-perf.com/2014/10/30/… "ng-bind est plus rapide car plus simple. L'interpolation doit passer par des étapes supplémentaires de vérification du contexte, jsonification de valeurs et plus. cela le rend légèrement plus lent. "
Konstantin Krass
29

ng-bind est mieux que {{...}}

Par exemple, vous pourriez faire:

<div>
  Hello, {{variable}}
</div>

Cela signifie que tout le texte Hello, {{variable}}entouré par <div>sera copié et stocké en mémoire.

Si à la place vous faites quelque chose comme ça:

<div>
  Hello, <span ng-bind="variable"></span>
</div>

Seule la valeur de la valeur sera stockée en mémoire et angulaire enregistrera un observateur (expression de surveillance) qui se compose uniquement de la variable.

J brian
la source
7
D'un autre côté, votre DOM est plus profond. Selon ce que vous faites, dans les gros documents, cela peut affecter les performances de rendu.
stephband
2
Ouais, je pense de la même manière que @stephband. Si vous souhaitez simplement afficher le nom et le prénom, par exemple. Pourquoi pas juste une interpolation? Il fonctionnera de la même manière car il exécutera les mêmes montres en 1 résumé. Comme: <div> {{firstName}} {{lastName}} </div> == <div> <span ng-bind = "firstName"> </span> <span ng-bind = "lastName"> </ span> </div> .. Et le premier semble meilleur. Je pense que cela dépend beaucoup de ce que vous voulez, mais au final, ils ont tous deux des avantages et des inconvénients.
pgarciacamou
3
<div ng-bind-template="{{ var1 }}, {{ var2}}"></div>est une alternative à {{}} et fonctionne comme ng-bind
northamerican
1
Ce n'est pas des pommes pour des pommes - vous introduisez un élément span dans l'un et pas dans l'autre. L'exemple avec ng-bindserait plus comparable à <div>Hello, <span>{{variable}}</span></div>.
iconoclaste du
15

Fondamentalement, la syntaxe à double bouclé est plus lisible naturellement et nécessite moins de frappe.

Les deux cas produisent la même sortie mais .. si vous choisissez d'aller avec, {{}}il y a une chance que l'utilisateur voit pendant quelques millisecondes {{}}avant que votre modèle ne soit rendu par angulaire. Donc, si vous en remarquez, {{}}il vaut mieux l'utiliser ng-bind.

Il est également très important que seul le fichier index.html de votre application angulaire puisse être non rendu {{}}. Si vous utilisez des directives dans ce cas, il n'y a aucune chance de le voir, car angular rend d'abord le modèle et l'ajoute ensuite au DOM.

hellopathe
la source
5
Chose intéressante, ce n'est pas la même chose. Je n'obtiens aucune sortie sur ng-bind = "anArrayViaFactory" vs {{anArrayViaFactory}}. J'ai rencontré ce problème lors de la tentative de sortie d'une réponse json dans un prototype jekyll mais en raison d'un conflit avec des modèles similaires {{}}, j'ai été forcé d'utiliser ng-bind. Un ng-bind à l'intérieur d'un bloc ng-repeat (élément dans anArrayViaFactory) affichera des valeurs.
eddywashere
5

{{...}}signifie une liaison de données bidirectionnelle. Mais, ng-bind est en fait destiné à la liaison de données unidirectionnelle.

L'utilisation de ng-bind réduira le nombre d'observateurs dans votre page. Par conséquent, ng-bind sera plus rapide que {{...}}. Donc, si vous souhaitez uniquement afficher une valeur et ses mises à jour, et ne souhaitez pas refléter son changement d'interface utilisateur vers le contrôleur, optez pour ng-bind . Cela augmentera les performances de la page et réduira le temps de chargement de la page.

<div>
  Hello, <span ng-bind="variable"></span>
</div>
Tessy Thomas
la source
4

Cela est dû au fait que {{}}le compilateur angulaire considère à la fois le nœud de texte et son parent car il existe une possibilité de fusion de 2 {{}}nœuds. Il existe donc des liens supplémentaires qui augmentent le temps de chargement. Bien sûr, pour quelques-unes de ces occurrences, la différence est négligeable, mais lorsque vous l'utilisez dans un répéteur d'un grand nombre d'éléments, cela aura un impact dans un environnement d'exécution plus lent.

Ambika Sukla
la source
2

entrez la description de l'image ici

La raison pour laquelle Ng-Bind est meilleure parce que,

Lorsque votre page n'est pas chargée ou lorsque votre Internet est lent ou lorsque votre site Web est chargé à moitié, vous pouvez voir que ce type de problèmes (vérifiez la capture d' écran avec la marque de lecture) sera déclenché à l'écran, ce qui est complètement bizarre. Pour éviter cela, nous devons utiliser Ng-bind

Vikas Kalapur
la source
1

ng-bind a aussi ses problèmes. Lorsque vous essayez d'utiliser des filtres angulaires , limit ou autre, vous pouvez avoir des problèmes si vous utilisez ng-bind . Mais dans d'autres cas, ng-bind est meilleur du côté UX. Quand l'utilisateur ouvre une page, il / elle verra (10ms-100ms) qui imprime des symboles ( {{... ...}} ), c'est pourquoi ng-bind est meilleur .

Hazarapet Tunanyan
la source
1

Il y a un problème de scintillement dans {{}}, comme lorsque vous actualisez la page, puis pour une courte expression de spam de temps, nous devons donc utiliser ng-bind au lieu de l'expression pour la représentation des données.

GAURAV ROY
la source
0

ng-bindest également plus sûr car il représente htmlune chaîne.

Ainsi, par exemple, '<script on*=maliciousCode()></script>'sera affiché sous forme de chaîne et ne sera pas exécuté.

raneshu
la source
0

Selon Angular Doc:
comme ngBind est un attribut d'élément, il rend les liaisons invisibles pour l'utilisateur pendant le chargement de la page ... c'est la principale différence ...

Fondamentalement, jusqu'à ce que tous les éléments dom ne soient pas chargés, nous ne pouvons pas les voir et parce que ngBind est un attribut sur l'élément, il attend que les doms entrent en jeu ... plus d'informations ci-dessous

ngBind
- directive dans le module ng

L' attribut ngBind indique à AngularJS de remplacer le contenu textuel de l'élément HTML spécifié par la valeur d'une expression donnée et de mettre à jour le contenu textuel lorsque la valeur de cette expression change.

En règle générale, vous n'utilisez pas directement ngBind , mais à la place, vous utilisez le balisage double bouclé comme {{expression}} qui est similaire mais moins verbeux.

Il est préférable d'utiliser ngBind au lieu de {{expression}} si un modèle est momentanément affiché par le navigateur dans son état brut avant qu'AngularJS ne le compile. Étant donné que ngBind est un attribut d'élément, il rend les liaisons invisibles pour l'utilisateur pendant le chargement de la page.

Une solution alternative à ce problème serait d'utiliser la directive ngCloak . visitez ici

pour plus d'informations sur le ngbind visitez cette page: https://docs.angularjs.org/api/ng/directive/ngBind

Vous pouvez faire quelque chose comme ça en tant qu'attribut, ng-bind :

<div ng-bind="my.name"></div>

ou faites une interpolation comme ci-dessous:

<div>{{my.name}}</div>

ou de cette façon avec les attributs ng-cloak dans AngularJs:

<div id="my-name" ng-cloak>{{my.name}}</div>

ng-cloak évitez de flasher sur le dom et attendez que tout soit prêt! c'est égal à l' attribut ng-bind ...

Alireza
la source