Angular - przesyłanie danych do i z komponentu za pomocą dekoratorów Input, Output i klasy EventEmmiter

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 3421 razy

Wstęp

Nadeszla wiekopomna chwila - jak mawiał Pawlak na pogrzebie swego brata. A więc nadeszla wiekopomna chwila, by znaleźć jakiś sprytny, żeby nie powiedzieć przebiegły sposób na komunikowanie się nadrzędnego komponentu z własnoręcznie utworzonym komponentem. Jak jednak tego niezwykłego czynu dokonać?! Pytam się jak? Z odsieczą biegną ku nam dwa rozwiązania, jednakże na tej stronie będę omawiał tylko jedno z nich, które jest słuszne ze względu na charakter komunikacji element rodziec → element dziecko. Tak więc do wysyłania informacji do wnętrza komponentu wykorzystuje się Angular-owy dekorator o jakże wymownej nazwie Input.

Z kolei wysyłanie danych na zewnątrz to nieco bardziej złożona sprawa, tutaj z odsieczą biegnie nie tylko dekorator o równie wymownej nazwie Output ale i również specjalna klasa EventEmitter.

Podróż do wnętrza komponentu, czyli wysyłanie danych do komponentu

Wiele elementów HTML ma atrybuty, do których można w łatwy sposób się podpiąć, żeby tylko był jakiś przebiegły sposób na utworzenie takiego własnego atrybutu! Okazuje się to jednak prostsze aniżeli odebranie dzieciakowi lizaka (nie żebym kiedykolwiek próbował). Albowiem za prawdę powiadam wam, że wystarczy jedynie utworzyć w kodzie klasy komponentu jedno pole i udekorować je w następujący sposób:

@Input() title: string = 'base title';

Zaś w kodzie HTML tegoż komponentu wystarczy umieścić następujący kod:

<h1>{{ title }}</h1>

Wtedy to w kodzie HTML innego komponentu można zagnieździć wcześniej utworzony komponent przekazując do jego wnętrza dane np. tak:

<app-my-component [title]='My title'></app-my-component>

Sam dekorator Input umożliwia ustawienie nazwy właściwości, po której będzie można wysyłać dane do wnętrza komponentu:

@Input('myTitle') title: string = 'base title';

Teraz w kodzie komponentu nadrzędnego:

<app-my-component [myTitle]="'My title'"></app-my-component>

Wyciąganie danych z komponentu

W przypadku wyciągania danych z komponentu sprawa nieco się komplikuje. Dzieje się tak ponieważ to komponent będzie decydował kiedy wyemitować informację z daną wartością. Najczęściej taka sytuacja powinna mieć miejsce, gdy wartość, która jest emitowana na zewnątrz się zmieniła. Nie ma jednak możliwości tutaj pobrania z komponentu wartości zmiennej w dowolnej chwili. Z tego też względu przechwycona wartość powinna być przechwytywana i przetrzymywana w zmiennej komponentu nadrzędnego.

W kodzie klasy komponentu dziecka należy napisać taki oto kod:

title: string = ''; @Input('myTitle') set setTitle(title: string) { this.title = title; this.titleEmitter.emit(title); } @Output() onTitleChanged: EventEmitter = new EventEmitter();

Teraz w kodzie HTML komponentu, w którym kontrolka została osadzona można podpiąć się pod zdarzenie i właściwość w następujący sposób:

<app-my-component [myTitle]="tile" (onTitleChanged)="onTitleChanged($event)"></app-my-component>

Oczywiście w klasie też trzeba zmienną title i metodę onTitleChanged zadeklarować:

title: string = ''; onTitleChanged(value) { console.log('Title changed: ', value); }

Żeby to zadziałało trzeba w ngOnInit ustawić zmienną title jakiś ciąg znaków:

ngOnInit() { this.title = 'Tytuł pod komponentu'; }

Co powinno wywołać wyświetlenie następującego console log-a:

Title changed: Tytuł komponentu
Propozycje książek