Zmienne szablonowe – #referencja
Zmienne szablonowe pozwalają „złapać” element HTML lub komponent za pomocą nazwy z kratką i używać go w innych miejscach szablonu. To proste narzędzie, które oszczędza dużo kodu TypeScript.
Czym jest zmienna szablonowa?
Wyobraź sobie, że chcesz wziąć to co użytkownik wpisał w pole tekstowe i wyświetlić to w innym miejscu strony – bez pisania ani jednej linii TypeScript. Właśnie do tego służą zmienne szablonowe.
Zmienna szablonowa to etykieta przyklejona do elementu HTML.
Dzięki niej możesz odwoływać się do tego elementu – czytać jego wartość,
wywoływać jego metody – bezpośrednio w kodzie HTML, bez pośrednictwa pliku
.ts.
W WPF każdy element ma właściwość Name lub x:Name
i odwołujesz się do niego z C# przez tę nazwę. Zmienna szablonowa Angulara
działa podobnie – daje elementowi nazwę – ale używasz jej bezpośrednio
w HTML, nie w TypeScript.
Składnia – znak # przed nazwą
Zmienną szablonową tworzymy dodając #nazwaZmiennej
jako atrybut dowolnego elementu HTML. Nazwa może być dowolna –
ważne żeby zaczynała się od #.
<!-- Zmienna szablonowa na elemencie input --> <input #mojePolee type="text"> <!-- Zmienna szablonowa na przycisku --> <button #mojPrzycisk class="btn btn-primary">Kliknij</button> <!-- Zmienna szablonowa na nagłówku --> <h2 #tytul>Nagłówek strony</h2> <!-- Teraz możemy używać tych zmiennych w CAŁYM szablonie --> <p>Wpisałeś: {{ mojePolee.value }}</p> <p>Tekst przycisku: {{ mojPrzycisk.textContent }}</p> <p>Nagłówek: {{ tytul.textContent }}</p>
Znak # jest też używany w CSS do selektorów ID
(np. #naglowek { color: red; }). To dwa różne zastosowania
tego samego znaku – w Angularze #nazwa jako atrybut HTML
tworzy zmienną szablonową, a nie selektor CSS.
Odczyt wartości pola formularza
Najczęstsze zastosowanie zmiennych szablonowych to odczytywanie
tego co użytkownik wpisał w pole input.
Przez zmienną szablonową mamy dostęp do właściwości value
– aktualnej zawartości pola.
Poniższy przykład wyświetla na żywo to co piszesz w polu tekstowym –
bez żadnego kodu w pliku .ts:
<div class="container mt-4"> <label class="form-label">Wpisz swoje imię:</label> <input #imieInput type="text" class="form-control" (input)="''" > <!-- Wyświetlamy wartość pola przez zmienną szablonową --> <p class="mt-3"> Wpisałeś: <strong>{{ imieInput.value }}</strong> </p> </div>
(input)="''"?
To zdarzenie (input) – reaguje na każde wciśnięcie klawisza
w polu. Przypisujemy mu pusty string '' żeby Angular
wiedział, że ma odświeżyć widok po każdym znaku. Bez tego
{{ imieInput.value }} nie zaktualizuje się na żywo.
O zdarzeniach (event binding) dowiesz się więcej
w osobnym materiale.
Właściwości dostępne przez zmienną szablonową
| Właściwość | Co zwraca? | Przykład |
|---|---|---|
.value |
Wartość wpisana w pole input |
imieInput.value |
.textContent |
Tekst wewnątrz elementu (np. <p>, <h1>) |
naglowek.textContent |
.checked |
Czy checkbox jest zaznaczony (true/false) |
zgodaCheckbox.checked |
.disabled |
Czy element jest zablokowany | przycisk.disabled |
Przekazanie wartości do metody
Zmienną szablonową możemy też przekazać jako argument do metody komponentu. To połączenie szablonu z TypeScriptem – zamiast odczytywać wartość w HTML, oddajemy ją do przetworzenia klasie.
Klasyczny przykład: pole tekstowe i przycisk. Po kliknięciu przycisku wartość z pola trafia do metody w TypeScript:
export class AppComponent { wynik: string = ''; przywitaj(imie: string): void { this.wynik = `Cześć, ${imie}! Witaj w Angularze!`; } }
<div class="container mt-4"> <div class="input-group mb-3"> <!-- 1. Tworzymy zmienną szablonową #imieRef --> <input #imieRef type="text" class="form-control" placeholder="Wpisz imię"> <!-- 2. Po kliknięciu przekazujemy .value do metody --> <button class="btn btn-primary" (click)="przywitaj(imieRef.value)" > Przywitaj </button> </div> <!-- 3. Wynik metody wyświetlamy przez interpolację --> <p class="alert alert-success">{{ wynik }}</p> </div>
Po wywołaniu metody możesz wyczyścić pole dodając do obsługi kliknięcia
przypisanie imieRef.value = '':
(click)="przywitaj(imieRef.value); imieRef.value = ''"
Średnik pozwala wykonać dwie instrukcje w jednej obsłudze zdarzenia.
Wiele zmiennych szablonowych naraz
W jednym szablonie możemy mieć dowolną liczbę zmiennych szablonowych. Każda musi mieć unikalną nazwę w obrębie szablonu.
Przykład prostego mini-kalkulatora – dwa pola i przycisk. Wszystko bez żadnej zmiennej w klasie, tylko przez zmienne szablonowe i wyrażenie w szablonie:
export class AppComponent { // Klasa jest pusta – całość działa przez zmienne szablonowe! }
<div class="container mt-4"> <h4>Mini kalkulator</h4> <div class="row g-2 align-items-center"> <div class="col-auto"> <input #liczbaA type="number" class="form-control" (input)="''" value="0"> </div> <div class="col-auto"><span>+</span></div> <div class="col-auto"> <input #liczbaB type="number" class="form-control" (input)="''" value="0"> </div> <div class="col-auto"><span>=</span></div> <div class="col-auto"> <!-- Suma obliczana bezpośrednio w szablonie --> <span class="fs-4 fw-bold text-success"> {{ +liczbaA.value + +liczbaB.value }} </span> </div> </div> </div>
+liczbaA.value a nie samo liczbaA.value?
Właściwość .value zwraca zawsze string (tekst),
nawet gdy pole jest typu number. Operator + przed
wartością konwertuje string na liczbę. Bez tego zamiast dodawania dostałbyś
sklejanie tekstu: "5" + "3" = "53" zamiast 8.
Zasięg zmiennej szablonowej
Zmienna szablonowa jest dostępna w całym szablonie komponentu,
ale z jednym ważnym wyjątkiem – nie działa wewnątrz zagnieżdżonych struktur
takich jak @if czy @for, jeśli jest zdefiniowana
poza nimi (i odwrotnie).
✅ Zmienna dostępna w całym szablonie
<input #pole type="text"> <!-- Działa – pole i p są na tym samym poziomie --> <p>{{ pole.value }}</p> <button (click)="zapisz(pole.value)">Zapisz</button>
❌ Zmienna poza zasięgiem @if
@if (warunek) {
<input #pole type="text">
}
<!-- Nie działa! pole jest wewnątrz @if -->
<p>{{ pole.value }}</p>
Zmienną szablonową definiuj w tym samym bloku (@if,
@for lub główny szablon) w którym jej używasz.
Jeśli potrzebujesz wartości pola w wielu miejscach szablonu –
umieść input poza blokami warunkowymi.
Częste błędy
❌ Błąd 1 – Dwie zmienne o tej samej nazwie
❌ Źle – duplikat nazwy
<input #pole type="text"> <input #pole type="number"> <!-- Angular nie wie, do którego się odwołujemy -->
✅ Dobrze – unikalne nazwy
<input #nazwaInput type="text"> <input #wiekInput type="number">
❌ Błąd 2 – Brak zdarzenia przy wyświetlaniu na żywo
❌ Pole nie aktualizuje się na żywo
<!-- Brak zdarzenia – Angular nie odświeża widoku --> <input #imie type="text"> <p>{{ imie.value }}</p> <!-- Wynik nie zmieni się po wpisaniu tekstu -->
✅ Zdarzenie (input) wymusza odświeżenie
<input #imie type="text" (input)="''"> <p>{{ imie.value }}</p> <!-- Teraz wynik aktualizuje się na bieżąco -->
❌ Błąd 3 – Użycie zmiennej w TypeScript
❌ Zmienna szablonowa nie działa w .ts
// .ts – to nie zadziała! zapiszDane(): void { // imieInput to zmienna szablonowa – nie istnieje tutaj const wartosc = imieInput.value; // ❌ BŁĄD }
✅ Przekaż wartość jako argument
<!-- .html – przekaż .value do metody --> <button (click)="zapiszDane(imieInput.value)"> Zapisz </button> // .ts – metoda otrzymuje wartość jako parametr zapiszDane(wartosc: string): void { console.log(wartosc); // ✅ działa }
Zadanie – formularz dodawania produktu
Stwórz aplikację z prostym formularzem, która używa zmiennych szablonowych. Klasa komponentu może zawierać tylko metody i tablicę produktów – resztę zrób przez zmienne szablonowe.
Formularz powinien zawierać:
- Pole tekstowe „Nazwa produktu” z zmienną szablonową
#nazwaInput - Pole numeryczne „Cena” z zmienną szablonową
#cenaInput - Przycisk „Dodaj produkt”
Po kliknięciu przycisku:
- Wywołaj metodę
dodajProdukt(nazwa, cena)przekazując wartości pól - Metoda dodaje produkt do tablicy w klasie
- Wyczyść pola formularza (
nazwaInput.value = '')
Pod formularzem wyświetl:
- Podgląd wpisywanej nazwy i ceny na żywo (przez
{{ nazwaInput.value }}) - Listę dodanych produktów (na razie może być w tabelce Bootstrap –
@forpoznamy w następnym temacie, na razie wystarczy że metoda działa)
W następnym materiale poznamy dyrektywy warunkowe @if i @else – mechanizm wyświetlania różnych fragmentów HTML w zależności od warunków logicznych.