AngularJS: Dlaczego ng-bind jest lepszy niż {{}} w angular?

401

Byłem w jednej z kątowych prezentacji, a jedna z osób na wspomnianym spotkaniu ng-bindjest lepsza niż {{}}wiążąca.

Jednym z powodów jest ng-bindumieszczenie zmiennej na liście obserwacyjnej i tylko w przypadku zmiany modelu dane są wypychane do widoku, z drugiej strony {{}}interpolują wyrażenie za każdym razem (myślę, że to cykl kątowy) i przesuwają wartość, nawet jeśli wartość się zmieniła lub nie.

Mówi się również, że jeśli nie masz dużo danych na ekranie, możesz użyć, {{}}a problem z wydajnością nie będzie widoczny. Czy ktoś może mi rzucić nieco światła na ten problem?

Nair
źródło
3
Czy mógłbyś sprawdzić, czy moja odpowiedź jest lepsza
Konstantin Krass
{{}} moim zdaniem nie jest praktyczne, widz zobaczy Twój tag przed całkowitym załadowaniem danych. Zastanawiam się, czy zespół Angular kiedykolwiek rozwiąże ten problem.
Jerry Liang
2
@Blazemonger: Czy nie możesz po prostu dołączyć atrybutu ng-cloak, aby zapobiec chwilowemu wyświetlaniu szablonów?
supershnee

Odpowiedzi:

322

Jeśli nie używasz ng-bind, zamiast tego coś takiego:

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

może być wyświetlany rzeczywisty Hello, {{user.name}}przez sekundę, zanim user.namezostanie rozwiązany (przed załadowaniem danych)

Możesz zrobić coś takiego

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

jeśli to dla ciebie problem.

Innym rozwiązaniem jest użycie ng-cloak.

zasada holograficzna
źródło
3
Na podstawie tego, co mówisz, nie ma żadnego spadku wydajności, jeśli użyjemy {{}}? Powiedziano mi, że jeśli użyjesz {{}}, za każdym razem spowoduje to inerpolate i wygeneruje wynik, nawet jeśli model się nie zmieni.
Nair
4
I jak używać ng-bind, jeśli nie chcę zawijać user.name wewnątrz tagu span? Jeśli użyję nawiasów klamrowych, otrzymam czyste imię, bez tagów HTML
Victor
5
@KevinMeredith wygląda tak po załadowaniu HTML, ale kątowe nie (jeszcze). Pamiętaj, że mówimy o szablonach po stronie klienta. Całą interpolację należy wykonać w przeglądarce ładującej aplikację. Zwykle obciążenia kątowe są wystarczająco szybkie, aby nie były zauważalne, ale w niektórych przypadkach staje się problemem. Więc ng-cloakzostał wynaleziony, aby naprawić ten problem.
zasada holograficzna
17
dla mnie to nie jest odpowiedź na pytanie, dlaczego ngBind jest lepszy. To po prostu sposób użycia ngBind zamiast adnotacji {{}} i odniesienia do ngCloak.
Konstantin Krass,
4
@Victor jest również miejsce, w ng-bind-templatektórym można połączyć oba podejścia: ng-bind-template="Hello, {{user.name}}"tutaj wiązanie nadal zapewnia wzrost wydajności i nie wprowadza żadnego dalszego zagnieżdżania
łup
543

Widoczność:

Podczas gdy twój angularjs ładuje się, użytkownik może zobaczyć umieszczone w nawiasach klamrowych html. Można to rozwiązać za pomocą ng-cloak. Ale dla mnie jest to obejście, którego nie muszę używać, jeśli używam ng-bind.


Wydajność:

{{}}Jest znacznie wolniejszy .

Jest ng-bindto dyrektywa i spowoduje umieszczenie obserwatora na przekazywanej zmiennej. Więc ng-bindbędzie miała zastosowanie tylko, gdy przeszedł wartość ma faktycznie zmienić .

Z drugiej strony wsporniki będą sprawdzane i odświeżane w każdym $digest , nawet jeśli nie jest to konieczne .


Obecnie tworzę dużą aplikację na jednej stronie (~ 500 powiązań na wyświetlenie). Zmiana z {{}} na ścisłą ng-bindpozwoliła nam zaoszczędzić około 20% na każdym scope.$digest.


Sugestia :

Jeśli korzystasz z modułu tłumaczenia, takiego jak tłumaczenie kątowe , zawsze preferuj dyrektywy przed opisami w nawiasach.

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

Jeśli potrzebujesz funkcji filtrowania, lepiej skorzystaj z dyrektywy, która faktycznie korzysta z niestandardowego filtra. Dokumentacja usługi $ filter


AKTUALIZACJA 28.11.2014 (ale może nie na temat):

W Angular 1.3x wprowadzono bindoncefunkcjonalność. Dlatego możesz raz powiązać wartość wyrażenia / atrybutu (zostanie powiązana, gdy! = 'Undefined').

Jest to przydatne, gdy nie oczekuje się zmiany wiązania.

Użycie: Umieść ::przed oprawą:

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

Przykład:

ng-repeataby wyświetlić niektóre dane w tabeli, z wieloma powiązaniami na wiersz. Powiązania translacji, wyniki filtrów, które są wykonywane w każdym skrócie zakresu.

Konstantin Krass
źródło
32
to lepsza odpowiedź
NimChimpsky
13
Z tego, co mogę powiedzieć ze źródła (stan na 24.11.2014), interpolacja kręcona jest obsługiwana tak jak dyrektywa (patrz addTextInterpolateDirective () w ng / compile.js). Używa również $ watch, więc DOM nie jest dotykany, jeśli tekst się nie zmienia, nie „brudne sprawdzanie i odświeżanie” przy każdym $ skrócie, jak twierdzisz. Jednak przy każdym $ skrócie obliczane są interpolowane ciągi wyników. Po prostu nie jest przypisany do węzła tekstowego, chyba że się zmieni.
Matti Virkkunen
6
Napisałem test wydajności do oceny wewnętrznej. Miał 2000 pozycji w powtórzeniu ng i wyświetlał 2 atrybuty w obiekcie, więc powiązania 2000 x 2. Wiązania różnią się: Pierwsze wiązanie było tylko wiązaniem w zakresie. Sekundy miały wiązanie i zwykły HTML. Wynik: wiązanie ng było szybsze o około 20% na zastosowanie. Wydaje się, że bez sprawdzania kodu dodatkowy zwykły HTML z kędzierzawym wyrażeniem w elemencie HTML zajmuje jeszcze więcej czasu.
Konstantin Krass
2
Chcę tylko zaznaczyć, że zgodnie z testami tutaj: jsperf.com/angular-bind-vs-brackets wydają się pokazywać, że nawiasy są SZYBCIEJ niż bindować. (Uwaga: taktami są ops na sekundę, więc im dłużej, tym lepiej). I jak podkreślają poprzednie komentarze, ich mechanizmy oglądania są ostatecznie identyczne.
Warren,
1
Ponieważ nie podajesz żadnego źródła, dam ci jedno: ng-perf.com/2014/10/30/... "ng-bind jest szybszy, ponieważ jest prostszy. Interpolacja musi przejść dodatkowe kroki weryfikacji kontekstu, jsonifikacji wartości i więcej. To sprawia, że ​​jest nieco wolniejszy. ”
Konstantin Krass,
29

ng-bind jest lepszy niż {{...}}

Na przykład możesz wykonać:

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

Oznacza to, że cały Hello, {{variable}}załączony tekst <div>zostanie skopiowany i zapisany w pamięci.

Jeśli zamiast tego zrobisz coś takiego:

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

Tylko wartość wartości zostanie zachowana w pamięci, a kątowy zarejestruje obserwatora (wyrażenie zegarka), który składa się tylko ze zmiennej.

J Brian
źródło
7
Z drugiej strony twój DOM jest głębszy. W zależności od tego, co robisz, w dużych dokumentach może to mieć wpływ na wydajność renderowania.
stephband
2
Tak, myślę tak samo jak @stephband. Jeśli chcesz na przykład wyświetlić imię i nazwisko. Dlaczego nie tylko interpolacja? Będzie działał w ten sam sposób, ponieważ będzie uruchamiał te same zegarki w 1 podsumowaniu. Jak: <div> {{firstName}} {{lastName}} </div> == <div> <span ng-bind = "firstName"> </span> <span ng-bind = "lastName"> </ span> </div> .. A pierwszy wygląda lepiej. Myślę, że zależy to w dużej mierze od tego, czego chcesz, ale ostatecznie oba mają zalety i wady.
pgarciacamou
3
<div ng-bind-template="{{ var1 }}, {{ var2}}"></div>jest alternatywą dla {{}} i działa jak ng-bind
northamerican
1
To nie są jabłka dla jabłek - wprowadzasz element rozpiętości w jednym, a nie w drugim. Przykład z ng-bindbyłby bardziej porównywalny do <div>Hello, <span>{{variable}}</span></div>.
iconoclast
15

Zasadniczo podwójna składnia jest bardziej naturalnie czytelna i wymaga mniej pisania.

Oba przypadki dają takie same dane wyjściowe, ale .. jeśli wybierzesz opcję, {{}}istnieje szansa, że ​​użytkownik zobaczy kilka milisekund, {{}}zanim szablon zostanie wyrenderowany przez kąt. Więc jeśli zauważysz, {{}}to lepiej jest użyć ng-bind.

Bardzo ważne jest również to, że tylko w pliku index.html aplikacji kątowej możesz nie renderować {{}}. Jeśli używasz dyrektyw, a następnie szablonów, nie ma szans, aby to zobaczyć, ponieważ kątowy najpierw renderuje szablon, a następnie dołącza go do DOM.

hellopath
źródło
5
Co ciekawe, to nie to samo. Nie otrzymuję danych wyjściowych na ng-bind = "anArrayViaFactory" vs {{anArrayViaFactory}}. Natknąłem się na ten problem, gdy próbowałem wygenerować odpowiedź json w protoype jekyll, ale z powodu konfliktu z podobnym szablonowaniem {{}} byłem zmuszony użyć ng-bind. Wiązanie ng wewnątrz bloku powtórzenia ng (element w anArrayViaFactory) wygeneruje wartości.
eddywashere
5

{{...}}oznacza dwukierunkowe wiązanie danych. Ale ng-bind jest w rzeczywistości przeznaczony do jednokierunkowego wiązania danych.

Użycie ng-bind zmniejszy liczbę obserwatorów na twojej stronie. Stąd ng-bind będzie szybszy niż {{...}}. Tak więc, jeśli chcesz tylko wyświetlić wartość i jej aktualizacje, a nie chcesz odzwierciedlać jej zmiany z interfejsu użytkownika z powrotem do kontrolera, przejdź do ng-bind . Zwiększy to wydajność strony i skróci czas ładowania strony.

<div>
  Hello, <span ng-bind="variable"></span>
</div>
Tessy Thomas
źródło
4

Jest tak, ponieważ {{}}w kompilatorze kątowym uwzględnia się zarówno węzeł tekstowy, jak i jego element nadrzędny, ponieważ istnieje możliwość scalenia 2 {{}}węzłów. Dlatego istnieją dodatkowe linkery, które wydłużają czas ładowania. Oczywiście dla kilku takich przypadków różnica jest nieistotna, jednak gdy używasz tego w repeaterze dużej liczby elementów, spowoduje to wpływ na wolniejsze środowisko wykonawcze.

Ambika Sukla
źródło
2

wprowadź opis zdjęcia tutaj

Powód, dla którego Ng-Bind jest lepszy, ponieważ,

Kiedy Twoja strona nie jest ładowana, gdy twój internet jest wolny lub gdy twoja strona jest w połowie ładowana, możesz zobaczyć, że tego rodzaju problemy (sprawdź zrzut ekranu ze znakiem odczytu) zostaną uruchomione na ekranie, który jest całkowicie dziwny. Aby tego uniknąć, powinniśmy użyć Ng-bind

Vikas Kalapur
źródło
1

ng-bind ma również swoje problemy. Kiedy próbujesz użyć filtrów kątowych , limitu lub czegoś innego, możesz mieć problem, jeśli użyjesz ng-bind . Ale w innym przypadku ng-bind jest lepszy po stronie UX. Kiedy użytkownik otworzy stronę, zobaczy (10ms-100ms), że drukuje symbole ( {{...}} ), dlatego ng-bind jest lepszy .

Hazarapet Tunanyan
źródło
1

W {{}} występuje pewien problem z migotaniem, np. Kiedy odświeżasz stronę, wtedy przez krótki czas widoczny jest wyraz wyrażenia czasu, więc do przedstawienia danych powinniśmy użyć ng-bind zamiast wyrażenia.

GAURAV ROY
źródło
0

ng-bindjest również bezpieczniejszy, ponieważ reprezentuje htmljako ciąg.

Na przykład '<script on*=maliciousCode()></script>'będzie wyświetlany jako ciąg i nie zostanie wykonany.

raneshu
źródło
0

Według Angular Doc:
Ponieważ ngBind jest atrybutem elementu, sprawia, że ​​powiązania są niewidoczne dla użytkownika podczas ładowania strony ... to główna różnica ...

Zasadniczo dopóki wszystkie elementy dom nie zostaną załadowane, nie możemy ich zobaczyć, a ponieważ ngBind jest atrybutem elementu, czeka, aż domeny wejdą do gry ... więcej informacji poniżej

ngBind
- dyrektywa w module ng

The atrybut ngBind mówi angularjs zastąpić zawartość tekstową określonego elementu HTML z wartością danego wyrazu, a także aktualizować zawartość tekstową, gdy wartość, że zmiany ekspresji.

Zazwyczaj nie używasz ngBind bezpośrednio , ale zamiast tego używasz podwójnego, kręconego znacznika, takiego jak {{wyrażenie}}, który jest podobny, ale mniej szczegółowy.

Preferowane jest użycie ngBind zamiast {{wyrażenie}}, jeśli przeglądarka chwilowo wyświetla szablon w stanie surowym, zanim AngularJS go skompiluje. Ponieważ ngBind jest atrybutem elementu, sprawia, że ​​powiązania są niewidoczne dla użytkownika podczas ładowania strony.

Alternatywnym rozwiązaniem tego problemu byłoby pomocą ngCloak dyrektywy. odwiedź tutaj

Aby uzyskać więcej informacji na temat ngbind odwiedź tę stronę: https://docs.angularjs.org/api/ng/directive/ngBind

Możesz zrobić coś takiego jako atrybut, ng-bind :

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

lub wykonaj interpolację jak poniżej:

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

lub w ten sposób z atrybutami ng-cloak w AngularJs:

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

ng-cloak unikaj flashowania na domku i poczekaj, aż wszystko będzie gotowe! jest to równe atrybutowi ng-bind ...

Alireza
źródło