Czym naprawdę różnią się [] i {{}} w Angularze
Brak rozumienia []
i {{}}
w Angularze może nam przysporzyć wielu problemów podczas pracy. Może nam to m.in. trochę namieszać podczas pracy z szablonami - a dokładnie w przypadku dokładnego określania, co te szablony mają robić. Można też czasem spędzić za dużo czasu na poszukiwaniu jakiegoś błędu, który często wynika właśnie z niewłaściwego rozumienia tych notacji. Wyjaśnię tutaj, co te dwa wiązania właściwie robią i co sprawia, że ich użycie może nas wprowadzić w błąd.
Na pewno znacie powszechne użycie wiązań {{}}
:
<h1>{{title}}</h1>
Znacie też raczej powszechne użycie []
(lub property bindings):
<img [src]="imgsrc">
Jednak, czy wiecie tak naprawdę, co do czego służy? I dlaczego używamy ich w takim, a nie innym kontekście? Często używa się {{}}
do umieszczania tekstu w jakimś elemencie. []
jest natomiast z reguły używane do przyłączenia się do jakiejś właściwości. Czy zastanawialiście się jednak, dlaczego właściwość formControlName
nie używa []
w formularzach reaktywnych?
<input formControlName="title" >
Zrozumienie podstaw działania tych dwóch elementów pomoże Wam w rozpoznaniu przypadków, w których powinno się użyć []
, {{}}
, a w których żadnego z nich (tak jak z właściwością formControlName
). Naszą dyskusję rozpoczniemy od omówienia różnicy między poniższymi linijkami kodu:
<img [src]="imgsrc">
<img src="{{imgsrc}}">
Obie mają taki sam wynik - ustawiają atrybut src
tagu image
. Ważne jest również to, że obie linijki wyliczają właściwość imgsrc
, która musi znajdować się w Twoim komponencie. W obu przypadkach wykorzystują składnię Angulara, a zatem możemy zrobić coś takiego:
<img [src]="'/images/' + name + '.png'">
<img src="{{'/images/' + name + '.png'}}">
Oto wyrażenie, które dodaje ciąg znaków do adresu URL danego obrazu, łącząc ze sobą katalog główny, nazwę i rozszerzenie. Zauważcie, że nie należy łączyć []
i {{}}
w tym samym atrybucie - Angular wyrzuci błąd. Jaka jest zatem prawdziwa różnica między tymi dwoma?
Wszystko sprowadza się do ich funkcjonowania - {{}}
to pewien rodzaj interpolacji stringów. Zastępuje ciąg znaków HTML rezultatem połączenia. Następnie wszystko zostaje wykonane. []
działa trochę inaczej. Manipuluje DOM-em po przetworzeniu HTML-a przez przeglądarkę.
Binding [src]
obsługuje właściwość src
obiektu image
, a nie atrybut src
od tagu img
. Jest to istotne, ponieważ [] może zachowywać typy danych (bo nie jest formą interpolacji stringów).
Spójrzmy na poniższy kod:
<input formControlName="isVisible" name="isVisible" type="radio"
value="true"> True
<input formControlName="isVisible" name="isVisible" type="radio"
value="false"> False
HTML nie łączy w tym formularzu isVisible
z wartościami boolowskimi true
i false
. Kod ten tworzy powiązanie właściwości isVisible
z ciągiem znaków true
lub false
. Co więcej, każdy niepusty string przy prostym porównaniu zostanie uznany za true
. Jeśli użyjemy więc tego jako wyrażenie nglf
<h1 *ngIf="myForm.value.isVisible">I'm only visible if the radio
button is set to True</h1>
To nie z tego nie wyniknie - nglf
zawsze wykona się jako true
. Jeśli zrobimy wiązanie do wartości właściwości
<input formControlName="isVisible" name="isVisible" type="radio"
[value]="true"> True
<input formControlName="isVisible" name="isVisible" type="radio"
[value]="false"> False
To stworzmy wiązanie właściwości isVisible
z boolowskim true
/false
. Nie można tego jednak dokonać, używając {{}}
.
<input formControlName="isVisible" name="isVisible" type="radio"
value="{{true}}"> True
<input formControlName="isVisible" name="isVisible" type="radio"
value="{{false}}"> False
Bo otrzymamy taki sam wynik, jak w pierwszym przykładzie - będzie to po prostu ciąg znaków „true” i „false”.
Powyższe rozważania dotyczą pewnych podstaw, które nie wszyscy developerzy Angulara rozumieją. Property bindings zmieniają DOM i zachowują typy danych. {{}}
to interpolacja stringów HTMLa - ich rezultatem zawsze jest ciąg znaków.
Ta wiedza pozwoli Wam uniknąć wielu bugów.
Miłego kodowania!
Oryginał tekstu w języku angielskim możesz przeczytać tutaj.