AngularJS: Perché ng-bind è meglio di {{}} in angolare?


401

Ero in una presentazione angolare e una delle persone nella riunione menzionata ng-bindè meglio che {{}}impegnativa.

Uno dei motivi, ng-bindinserisci la variabile nell'elenco di controllo e solo quando si verifica un cambio di modello, i dati vengono spinti a visualizzare, d'altra parte, {{}}interpolano l'espressione ogni volta (suppongo sia il ciclo angolare) e spingono il valore, anche se il valore è cambiato o meno.

Inoltre si dice che, se non ci sono molti dati sullo schermo, è possibile utilizzare {{}}e il problema delle prestazioni non sarà visibile. Qualcuno può fare luce su questo problema per me?



3
Potresti controllare se la mia risposta è migliore
Konstantin Krass,

{{}} secondo me non è pratico, lo spettatore vedrà il tuo tag prima che i dati vengano caricati completamente. Mi chiedo se il team di Angular risolverà mai questo problema.
Jerry Liang,

2
@Blazemonger: non puoi semplicemente includere l'attributo ng-cloak per impedire che i modelli vengano momentaneamente visualizzati?
supershnee,

Risposte:


322

Se non si utilizza ng-bind, invece qualcosa del genere:

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

potresti vedere l'effettivo Hello, {{user.name}}per un secondo prima che user.namevenga risolto (prima che i dati vengano caricati)

Potresti fare qualcosa del genere

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

se questo è un problema per te.

Un'altra soluzione è usare ng-cloak.


3
Sulla base di quello che stai dicendo, non ci sono risultati positivi se usiamo {{}}? Mi è stato detto, se usi {{}}, ogni volta, che diventerà inerpolato e genererà il risultato anche se il modello non cambia.
Nair,

4
E come usare ng-bind se non voglio racchiudere user.name nel tag span? Se utilizzo parentesi graffe otterrò un nome pulito, senza tag html
Victor

5
@KevinMeredith appare così quando l'HTML è stato caricato, ma angolare no (ancora). Ricorda che stiamo parlando del modello lato client. Tutta l'interpolazione deve essere eseguita nel browser caricando l'app. Di solito i carichi angolari sono abbastanza veloci da non essere evidente, ma in alcuni casi diventa un problema. Quindi, è ng-cloakstato inventato per riparare questo problema.
principio olografico

17
per me, questa non è la risposta alla domanda, perché ngBind è migliore. È solo come usare ngBind invece dell'annotazione {{}} e un riferimento a ngCloak.
Konstantin Krass,

4
@Victor c'è anche un punto in ng-bind-templatecui è possibile combinare entrambi gli approcci: ng-bind-template="Hello, {{user.name}}"qui la rilegatura offre ancora il potenziamento delle prestazioni e non introduce ulteriori annidamenti
loother

543

Visibilità:

Mentre angularjs sta eseguendo il bootstrap, l'utente potrebbe vedere le parentesi posizionate nell'html. Questo può essere gestito con ng-cloak. Ma per me questa è una soluzione alternativa, che non ho bisogno di usare, se uso ng-bind.


Prestazione:

Il {{}}è molto più lento .

Questa ng-bindè una direttiva e posizionerà un watcher sulla variabile passata. Quindi ng-bindverrà applicato solo quando il valore passato cambia effettivamente .

Le parentesi invece saranno sporche controllate e aggiornate in ogni $digest , anche se non è necessario .


Attualmente sto realizzando una grande app a pagina singola (~ 500 associazioni per visualizzazione). Passare da {{}} a rigoroso ci ha ng-bindfatto risparmiare circa il 20% in ogni scope.$digest.


Suggerimento :

Se usi un modulo di traduzione come angular-translate , preferisci sempre le direttive prima dell'annotazione tra parentesi.

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

Se hai bisogno di una funzione di filtro, meglio scegliere una direttiva, che in realtà utilizza solo il tuo filtro personalizzato. Documentazione per il servizio $ filter


AGGIORNAMENTO 28.11.2014 (ma forse fuori tema):

In Angular 1.3x è bindoncestata introdotta la funzionalità. Pertanto è possibile associare il valore di un'espressione / attributo una volta (verrà associato quando! = 'Non definito').

Questo è utile quando non ti aspetti che il tuo legame cambi.

Utilizzo: Posiziona ::prima della rilegatura:

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

Esempio:

ng-repeatper generare alcuni dati nella tabella, con più associazioni per riga. Binding di traduzione, output di filtro, che vengono eseguiti in ogni digest dell'ambito.


32
questa è una risposta migliore
NimChimpsky,

13
Da quello che posso dire dalla fonte (al 24/11/2014), l'interpolazione riccia è gestita proprio come una direttiva (vedi addTextInterpolateDirective () in ng / compile.js). Utilizza anche $ watch, quindi il DOM non viene toccato se il testo non cambia, non lo "sporca controlla e aggiorna" su ogni $ digest come affermi. Ciò che viene fatto su ogni $ digest però è che viene calcolata la stringa di risultato interpolata. Non è semplicemente assegnato al nodo di testo a meno che non cambi.
Matti Virkkunen,

6
Ho scritto un test delle prestazioni per la valutazione interna. Aveva 2000 voci in una ripetizione ng e visualizzava 2 attributi nell'oggetto, quindi i collegamenti 2000x2. Le associazioni differiscono in: la prima associazione era solo la rilegatura in un arco di tempo. I secondi avevano un'associazione e qualche semplice HTML in esso. Il risultato: ng-bind è stato più veloce di circa il 20% per applicazione. Senza controllare il codice, a quanto pare, l'html semplice aggiuntivo con un'espressione riccia in un elemento html richiede ancora più tempo.
Konstantin Krass,

2
Voglio solo sottolineare che, secondo i test qui: jsperf.com/angular-bind-vs-brackets sembra mostrare che le parentesi sono più veloci del binding. (Nota: le barre sono ops al secondo, quindi più a lungo è meglio). E come sottolineano i commenti precedenti, i loro meccanismi di osservazione sono in definitiva identici.
Warren,

1
Poiché non stai fornendo alcuna fonte, te ne do una: ng-perf.com/2014/10/30/… "ng-bind è più veloce perché è più semplice. L'interpolazione deve passare attraverso ulteriori passaggi di verifica del contesto, la jsonificazione di valori e altro ancora. questo lo rende leggermente più lento. "
Konstantin Krass,

29

ng-bind è meglio di {{...}}

Ad esempio, potresti fare:

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

Ciò significa che l'intero testo Hello, {{variable}}racchiuso da <div>verrà copiato e archiviato in memoria.

Se invece fai qualcosa del genere:

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

Solo il valore del valore verrà memorizzato e angolare registrerà un watcher (espressione di controllo) che consiste solo nella variabile.


7
D'altra parte, il tuo DOM è più profondo. A seconda di ciò che stai facendo, nei documenti di grandi dimensioni ciò potrebbe influire sulle prestazioni di rendering.
stephband

2
Sì, penso allo stesso modo di @stephband. Se si desidera solo visualizzare il nome e il cognome, ad esempio. Perché non solo interpolazione? Funzionerà allo stesso modo perché eseguirà gli stessi orologi in 1 digest. Come: <div> {{firstName}} {{lastName}} </div> == <div> <span ng-bind = "firstName"> </span> <span ng-bind = "lastName"> </ span> </div> .. E il primo sembra migliore. Penso che dipenda molto da quello che vuoi ma alla fine entrambi hanno vantaggi e svantaggi.
pgarciacamou,

3
<div ng-bind-template="{{ var1 }}, {{ var2}}"></div>è un'alternativa a {{}} e funziona come ng-bind
northamerican il

1
Non si tratta di mele alle mele: stai introducendo un elemento di span in uno e non nell'altro. L'esempio con ng-bindsarebbe più comparabile a <div>Hello, <span>{{variable}}</span></div>.
iconoclasta

15

Fondamentalmente la sintassi a doppio riccio è più naturalmente leggibile e richiede meno digitazione.

Entrambi i casi producono lo stesso output ma ... se si sceglie di andare avanti {{}}c'è una possibilità che l'utente vedrà per alcuni millisecondi {{}}prima che il modello venga visualizzato in modo angolare. Quindi, se noti qualcosa, {{}}è meglio usarlo ng-bind.

Anche molto importante è che solo nel tuo index.html della tua app angolare puoi non renderizzare {{}}. Se stai usando le direttive, quindi i modelli, non c'è alcuna possibilità di vederlo perché angolare prima rende il modello e dopo lo aggiunge al DOM.


5
È interessante notare che non è lo stesso. Non ottengo alcun output su ng-bind = "anArrayViaFactory" vs {{anArrayViaFactory}}. Mi sono imbattuto in questo problema durante il tentativo di generare una risposta json in un protoype jekyll ma a causa di un conflitto con un simile modello {{}}, sono stato costretto a usare ng-bind. Un ng-bind all'interno di un blocco ng-repeat (elemento in anArrayViaFactory) genererà valori.
eddywashere,

5

{{...}}si intende l'associazione dati bidirezionale. Ma ng-bind è in realtà pensato per l'associazione dati unidirezionale.

L'uso di ng-bind ridurrà il numero di osservatori nella tua pagina. Quindi ng-bind sarà più veloce di {{...}}. Quindi, se vuoi solo visualizzare un valore e i suoi aggiornamenti e non vuoi riflettere la sua modifica dall'interfaccia utente al controller, allora scegli ng-bind . Ciò aumenterà le prestazioni della pagina e ridurrà il tempo di caricamento della pagina.

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

4

Questo perché con {{}}il compilatore angolare considera sia il nodo di testo sia il suo genitore in quanto esiste la possibilità di unire 2 {{}}nodi. Quindi ci sono linker aggiuntivi che si aggiungono al tempo di caricamento. Naturalmente per alcuni di questi casi la differenza è irrilevante, tuttavia quando lo si utilizza all'interno di un ripetitore di un gran numero di elementi, si avrà un impatto in un ambiente di runtime più lento.


2

inserisci qui la descrizione dell'immagine

Il motivo per cui Ng-Bind è migliore perché,

Quando la tua pagina non è caricata o quando Internet è lento o quando il tuo sito web è caricato a metà, puoi vedere questo tipo di problemi (Controlla lo screenshot con il segno Leggi) verrà attivato sullo schermo che è completamente strano. Per evitare ciò, dovremmo usare Ng-bind


1

Anche ng-bind ha i suoi problemi. Quando provi ad usare filtri angolari , limit o qualcos'altro, potresti avere problemi se usi ng-bind . Ma in altri casi, ng-bind è migliore nel lato UX. Quando l'utente apre una pagina, vedrà (10ms-100ms) che stampa i simboli ( {{...}} ), ecco perché ng-bind è migliore .


1

C'è un problema di sfarfallio in {{}} come quando si aggiorna la pagina, quindi per un breve spam si vede l'espressione del tempo, quindi dovremmo usare ng-bind invece di expression per la rappresentazione dei dati.


0

ng-bindè anche più sicuro perché rappresenta htmlcome una stringa.

Ad esempio, '<script on*=maliciousCode()></script>'verrà visualizzato come una stringa e non verrà eseguito.


0

Secondo Angular Doc:
Poiché ngBind è un attributo element, rende i binding invisibili all'utente durante il caricamento della pagina ... è la differenza principale ...

Fondamentalmente fino a quando tutti gli elementi dom non vengono caricati, non possiamo vederli e poiché ngBind è un attributo sull'elemento, attende fino a quando i dom entrano in gioco ... maggiori informazioni di seguito

ngBind
- direttiva nel modulo ng

L' attributo ngBind dice ad AngularJS di sostituire il contenuto del testo dell'elemento HTML specificato con il valore di una determinata espressione e di aggiornare il contenuto del testo quando cambia il valore di quella espressione.

In genere, non si utilizza ngBind direttamente , ma si utilizza invece il doppio markup riccio come {{espressione}} che è simile ma meno dettagliato.

È preferibile utilizzare ngBind anziché {{espressione}} se un modello viene momentaneamente visualizzato dal browser allo stato grezzo prima che AngularJS lo compili. Poiché ngBind è un attributo element, rende i binding invisibili all'utente durante il caricamento della pagina.

Una soluzione alternativa a questo problema sarebbe l'utilizzo della direttiva ngCloak . visita qui

per maggiori informazioni su ngbind visita questa pagina: https://docs.angularjs.org/api/ng/directive/ngBind

Potresti fare qualcosa del genere come attributo, ng-bind :

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

o fai l'interpolazione come di seguito:

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

o in questo modo con gli attributi ng-cloak in AngularJs:

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

ng-mantello evita di lampeggiare sul dom e aspetta che tutto sia pronto! questo è uguale all'attributo ng-bind ...


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.