AngularJS: ¿Por qué ng-bind es mejor que {{}} en angular?

401

Estuve en una de las presentaciones angulares y una de las personas en la reunión mencionada ng-bindes mejor que {{}}vinculante.

Una de las razones, ng-bindcoloca la variable en la lista de observación y solo cuando hay un cambio de modelo, los datos que se envían para ver, por otro lado, {{}}interpolarán la expresión cada vez (supongo que es el ciclo angular) y presionarán valor, incluso si el valor cambió o no.

También se dice que, si no tiene muchos datos en la pantalla, puede usarlos {{}}y el problema de rendimiento no será visible. ¿Alguien puede arrojar algo de luz sobre este tema para mí?

Nair
fuente
3
¿Podría comprobar si mi respuesta es mejor
Konstantin Krass
{{}} en mi opinión no es práctico, el espectador verá su etiqueta antes de que los datos se carguen por completo. Me pregunto si el equipo de Angular alguna vez solucionará este problema.
Jerry Liang
2
@Blazemonger: ¿No puedes incluir el atributo ng-cloak para evitar que las plantillas se muestren momentáneamente?
supershnee

Respuestas:

322

Si no está utilizando ng-bind, en su lugar algo como esto:

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

Es posible que vea lo real Hello, {{user.name}}por un segundo antes de que user.namese resuelva (antes de que se carguen los datos)

Podrías hacer algo como esto

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

si eso es un problema para ti.

Otra solución es usar ng-cloak.

principio holográfico
fuente
3
Según lo que está diciendo, ¿no hay un impacto en el rendimiento si usamos {{}}? Me dijeron, si usa {{}}, cada vez, eso se inerpolará y generará el resultado incluso si el modelo no cambia.
Nair
44
¿Y cómo usar ng-bind si no quiero envolver user.name dentro de la etiqueta span? Si uso llaves, obtendré un nombre limpio, sin etiquetas html
Victor
55
@KevinMeredith parece así cuando el HTML se ha cargado, pero angular no (todavía). Recuerde que estamos hablando de plantillas del lado del cliente. Toda la interpolación debe hacerse en el navegador que carga la aplicación. Por lo general, las cargas angulares son lo suficientemente rápidas para que no se note, pero en algunos casos se convierte en un problema. Entonces, ng-cloakfue inventado para reparar este problema.
principio holográfico
17
Para mí, esta no es la respuesta a la pregunta, ¿por qué ngBind es mejor? Es solo cómo usar ngBind en lugar de la anotación {{}} y una referencia a ngCloak.
Konstantin Krass
44
@Victor también es ng-bind-templatedonde puedes combinar ambos enfoques: ng-bind-template="Hello, {{user.name}}"aquí el enlace aún ofrece el aumento de rendimiento y no introduce ningún anidamiento adicional
loother
543

Visibilidad:

Mientras su angularjs es bootstrapping, el usuario puede ver sus corchetes colocados en el html. Esto se puede manejar con ng-cloak. Pero para mí esta es una solución, que no necesito usar, si la uso ng-bind.


Actuación:

El {{}}es mucho más lento .

Esta ng-bindes una directiva y colocará un observador en la variable pasada. Por lo tanto ng-bind, solo se aplicará cuando el valor pasado realmente cambie .

Los soportes, por otro lado, se revisarán sucios y se actualizarán en todos $digest , incluso si no es necesario .


Actualmente estoy creando una gran aplicación de una sola página (~ 500 enlaces por vista). Cambiar de {{}} a estricto ng-bindnos ahorró alrededor del 20% en cada uno scope.$digest.


Sugerencia :

Si usa un módulo de traducción como angular-translate , siempre prefiera las directivas antes de la anotación de corchetes.

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

Si necesita una función de filtro, es mejor ir a una directiva, que en realidad solo usa su filtro personalizado. Documentación para el servicio $ filter


ACTUALIZACIÓN 28.11.2014 (pero tal vez fuera del tema):

En Angular 1.3x bindoncese introdujo la funcionalidad. Por lo tanto, puede vincular el valor de una expresión / atributo una vez (se vinculará cuando! = 'Indefinido').

Esto es útil cuando no espera que cambie su enlace.

Uso: Coloque ::antes de su encuadernación:

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

Ejemplo:

ng-repeatpara generar algunos datos en la tabla, con múltiples enlaces por fila. Enlaces de traducción, salidas de filtro, que se ejecutan en cada resumen de alcance.

Konstantin Krass
fuente
32
esta es una mejor respuesta
NimChimpsky
13
Por lo que puedo decir de la fuente (a partir del 24/11/2014), la interpolación rizada se maneja como una directiva (vea addTextInterpolateDirective () en ng / compile.js). También usa $ watch, por lo que el DOM no se toca si el texto no cambia, no lo "revisa y actualiza" en cada $ digest como usted dice. Sin embargo, lo que se hace en cada resumen de $ es que se calcula la cadena de resultados interpolada. Simplemente no está asignado al nodo de texto a menos que cambie.
Matti Virkkunen
66
Escribí una prueba de rendimiento para evaluación interna. Tenía 2000 entradas en una repetición ng y mostraba 2 atributos en el objeto, por lo que los enlaces de 2000x2. Los enlaces difieren en: El primer enlace fue solo el enlace en un lapso. Los segundos tenían un enlace y algo de HTML simple. El resultado: ng-bind fue más rápido, se aplicó aproximadamente un 20% por alcance. Sin verificar el código, parece que html simple adicional con una expresión rizada en un elemento html lleva aún más tiempo.
Konstantin Krass
2
Solo quiero señalar que de acuerdo con las pruebas aquí: jsperf.com/angular-bind-vs-brackets parecen mostrar que los corchetes son MÁS RÁPIDOS que el enlace. (Nota: las barras son operaciones por segundo, por lo tanto, más tiempo es mejor). Y como señalan los comentarios anteriores, sus mecanismos de observación son, en última instancia, idénticos.
Warren
1
Como no está proporcionando ninguna fuente, le doy una: ng-perf.com/2014/10/30/… "ng-bind es más rápido porque es más simple. La interpolación tiene que pasar por pasos adicionales para verificar el contexto, jsonificación de valores y más. eso lo hace un poco más lento ".
Konstantin Krass
29

ng-bind es mejor que {{...}}

Por ejemplo, podrías hacer:

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

Esto significa que todo el texto Hello, {{variable}}encerrado <div>será copiado y almacenado en la memoria.

Si en cambio haces algo como esto:

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

Solo el valor del valor se almacenará en la memoria, y angular registrará un observador (expresión del reloj) que consiste solo en la variable.

J brian
fuente
77
Por otro lado, tu DOM es más profundo. Dependiendo de lo que esté haciendo, en documentos grandes esto podría afectar el rendimiento de la representación.
stephband
2
Sí, creo que de la misma manera que @stephband lo hace. Si solo desea mostrar el nombre y el apellido, por ejemplo. ¿Por qué no solo la interpolación? Funcionará de la misma manera porque ejecutará los mismos relojes en 1 resumen. Me gusta: <div> {{firstName}} {{lastName}} </div> == <div> <span ng-bind = "firstName"> </span> <span ng-bind = "lastName"> </ span> </div> .. Y el primero se ve mejor. Creo que depende mucho de lo que quieras, pero al final ambos tienen ventajas y desventajas.
pgarciacamou
3
<div ng-bind-template="{{ var1 }}, {{ var2}}"></div>es una alternativa a {{}} y funciona como ng-bind
2015
1
No se trata de manzanas con manzanas: estás introduciendo un elemento span en uno y no en el otro. El ejemplo con ng-bindsería más comparable a <div>Hello, <span>{{variable}}</span></div>.
iconoclasta
15

Básicamente, la sintaxis de doble rizado es más fácil de leer y requiere menos tipeo.

Ambos casos producen la misma salida, pero ... si elige continuar, {{}}existe la posibilidad de que el usuario vea durante algunos milisegundos {{}}antes de que su plantilla sea renderizada por angular. Entonces, si notas alguna, {{}}entonces es mejor usarla ng-bind.

También es muy importante que solo en su index.html de su aplicación angular pueda tener sin renderizar {{}}. Si está utilizando directivas, entonces plantillas, no hay posibilidad de ver eso porque angular primero renderiza la plantilla y luego la agrega al DOM.

hellopath
fuente
55
Curiosamente, no es lo mismo. No obtengo salida en ng-bind = "anArrayViaFactory" vs {{anArrayViaFactory}}. Me encontré con este problema al intentar generar una respuesta json en un prototipo jekyll, pero debido a un conflicto con plantillas similares {{}}, me vi obligado a usar ng-bind. Un ng-bind dentro de un bloque ng-repeat (elemento en anArrayViaFactory) generará valores.
eddywashere
5

{{...}}significa enlace de datos bidireccional. Pero, ng-bind en realidad está destinado para el enlace de datos unidireccional.

El uso de ng-bind reducirá la cantidad de observadores en su página. Por lo tanto, ng-bind será más rápido que {{...}}. Por lo tanto, si solo desea mostrar un valor y sus actualizaciones, y no desea reflejar su cambio de la interfaz de usuario al controlador, vaya a ng-bind . Esto aumentará el rendimiento de la página y reducirá el tiempo de carga de la página.

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

Esto se debe a que con {{}}el compilador angular considera tanto el nodo de texto como su padre, ya que existe la posibilidad de fusionar 2 {{}}nodos. Por lo tanto, hay vinculadores adicionales que aumentan el tiempo de carga. Por supuesto, para algunos de estos casos, la diferencia es irrelevante, sin embargo, cuando está utilizando esto dentro de un repetidor de gran cantidad de elementos, causará un impacto en un entorno de tiempo de ejecución más lento.

Ambika Sukla
fuente
2

ingrese la descripción de la imagen aquí

La razón por la cual Ng-Bind es mejor porque,

Cuando su página no está cargada o cuando su Internet es lento o cuando su sitio web se cargó a la mitad, puede ver que este tipo de problemas (Verificar la captura de pantalla con la marca de lectura) se activará en la pantalla, que es completamente extraña. Para evitarlo, debemos usar Ng-bind

Vikas Kalapur
fuente
1

ng-bind también tiene sus problemas. Cuando intentas usar filtros angulares , límite u otra cosa, quizás puedas tener problemas si usas ng-bind . Pero en otro caso, ng-bind es mejor en el lado de UX. Cuando el usuario abre una página, verá (10ms-100ms) que imprime símbolos ( {{...}} ), por eso es mejor ng-bind .

Hazarapet Tunanyan
fuente
1

Hay un problema de parpadeo en {{}}, como cuando actualiza la página y, por un breve período de tiempo, se ve la expresión. Por lo tanto, deberíamos usar ng-bind en lugar de expresión para la representación de datos.

GAURAV ROY
fuente
0

ng-bindtambién es más seguro porque se representa htmlcomo una cadena.

Entonces, por ejemplo, '<script on*=maliciousCode()></script>'se mostrará como una cadena y no se ejecutará.

raneshu
fuente
0

Según Angular Doc:
dado que ngBind es un atributo de elemento, hace que los enlaces sean invisibles para el usuario mientras se carga la página ... es la principal diferencia ...

Básicamente, hasta que no se carguen todos los elementos dom , no podemos verlos y debido a que ngBind es un atributo en el elemento, espera hasta que los doms entren en juego ... más información a continuación

ngBind
- directiva en el módulo ng

El atributo ngBind le dice a AngularJS que reemplace el contenido de texto del elemento HTML especificado con el valor de una expresión dada, y que actualice el contenido de texto cuando cambie el valor de esa expresión.

Por lo general, no usa ngBind directamente , sino que usa el marcado doble rizado como {{expresión}} que es similar pero menos detallado.

Es preferible usar ngBind en lugar de {{expresión}} si el navegador muestra momentáneamente una plantilla en su estado bruto antes de que AngularJS la compile. Como ngBind es un atributo de elemento, hace que los enlaces sean invisibles para el usuario mientras se carga la página.

Una solución alternativa a este problema sería usar la directiva ngCloak . visitar aquí

Para obtener más información sobre ngbind, visite esta página: https://docs.angularjs.org/api/ng/directive/ngBind

Podría hacer algo como esto como atributo, ng-bind :

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

o hacer la interpolación de la siguiente manera:

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

o de esta manera con los atributos ng-cloak en AngularJs:

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

¡ng-cloak evita parpadear en el dom y espera hasta que todo esté listo! esto es igual al atributo ng-bind ...

Alireza
fuente