Co to jest Data Binding?
Często omawiając Angulara lub Reacta wspomina się o data binding'u. Czym ono jest? Dziś chciałbym przybliżyć tę koncepcję, bazując na przykładach.
Z tego artykułu dowiesz się:
Co to jest data binding?
Jakie mamy rodzaje wiązań danych?
Co to jest składnia "bananas in the box"?
Jak wyglada komunikacja pomiędzy komponentami w React?
Będę szczery.
Chodzi o relacje. Ale nie o byle jakie relacje. Chodzi o to, co mamy i jak to przekażemy dalej. Chodzi też o to, jak ta informacja do nas wróci. W końcu, chodzi po prostu o to, że w świecie programowania nie da się nie komunikować. Brzmi głupio, w szczególności w nasyconej stereotypami o programistach zamkniętych w piwnicach, rzeczywistości. Prawda jest taka, że każda aplikacja składa się z różnych warstw, które w trybie ciągłym wymieniają się danymi.
Po co to robią? Ponieważ czasami dane trzeba gdzieś zapisać, czasami dane trzeba zaktualizować w innym miejscu, a czasami po prostu poinformować inną warstwę o nowych danych, aby mogła odpowiednio zareagować.
Co to jest Data Binding?
Data Binding można przetłumaczyć jako wiązania danych. Najprościej rzecz ujmując jest to mechanizm w programowaniu, który jest odpowiedzialny za łączenie i synchronizację danych z dwóch różnych źródeł.
Spotkać się z nim możemy w wielu miejscach. Najbardziej klasyczny przykład to połączenie widoku aplikacji (User Interface) z danymi, które na tym widoku mają się znaleźć. Co ważne i wartościowe, zmiana danych w jednym miejscu automatycznie odświeży te dane w innym miejscu.
Zanim skupimy się na różnych rodzajach tworzonych powiązań, chciałbym zwrócić uwagę na fakt, że nie powinniśmy wiązać tej techniki tylko ze światem Javascriptu. Z Data Binding spotkamy się zarówno w aplikacjach webowych (zarówno w Angularze, jak i React’ie), aplikacjach mobilnych czy w technologiach backendowych (tutaj warto zwrócić uwagę chociażby na JavaFX, Java Spring, ASP.NET czy Windows Presentation Foundation). Każda z wyżej wymienionych technologii wykorzystuje Data Binding do tworzenia dynamicznych interakcji pomiędzy modelami danych a widokiem.
W jedną czy w dwie strony?
Już wyżej wspomniałem, że dane mogą być przekazywane w różny sposób. W zasadzie sprowadza się to do tego, kto z kim może się komunikować oraz kto ma na kogo wpływ. Możemy wyróżnić jednokierunkowe wiązanie danych (one-way binding) oraz dwukierunkowe wiązanie danych (two-way binding).
Jednokierunkowe wiązania są stosunkowo prostymi wiązaniami. Chodzi w nich o to, że dane przepływają tylko w jednym kierunku. Najczęściej będzie to związane z wyświetleniem danych z modelu na widoku. W przypadku Angulara dobrym przykładem byłby komponent, gdzie mamy rozbicie na plik widoku (HTML) oraz plik logiki / komponentu (TS). Plik w Typescript będzie w naszym przypadku modelem danych, który przekaże dane do widoku, gdzie zostaną one wyświetlone. Spójrzmy na poniższy przykład:
W klasie AppComponent istnieje publiczne pole title, zawierające tekst „Hello!”. Zwróćcie uwagę, że w pliku html powiązanym z tym komponentem zmienna title jest wykorzystywana w notacji z podwójnymi nawiasami klamrowymi. Dane zostaną wyświetlone na widoku, ale widok nie może wprowadzić żadnych zmian w modelu, tj. w pliku komponentu.
Architektura React’a zakłada natomiast domyślnie jednokierunkowy przepływ danych. Zwróćmy uwagę, na fakt, że dane są przekazywane pomiędzy komponentami za pośrednictwem propsów (component properties) tylko w jednym kierunku.
Komponent Button będzie wyświetlał etykietę na podstawie danych, które otrzyma „z góry”, z komponentu App. Jak widać działa to tylko w jedną stronę, komponent Button nie może wpłynąć na kształt danych w komponencie nadrzędnym.
Banany w pudełku
Zdarzyć się może jednak sytuacja, w której będziemy chcieli przekazać dane do widoku i odpowiednio zmodyfikować model. Zasadniczo wiązanie dwukierunkowe pozwala nam odzwierciedlić zmianę na widoku, gdy dane w modelu się zmienią, ale również zaktualizować model, gdy po stronie widoku wystąpi zmiana, np. poprzez działanie użytkownika.
Przykładowo: wykorzystujemy w naszej aplikacji formularz, z którego dane chcemy dalej przetworzyć z poziomu naszego komponentu, tak aby móc wykonać kolejne kroki związane z wyborami użytkownika. Standardowo będziemy tworzyć zdarzenie, które będzie wykorzystywało wprowadzone dane do tego, aby przesłać je do modelu i tam je obsłużyć.
Słynne banany w pudełku (ang. Banana in the box) to nic innego jak standard zapisu, który pozwala nam na dwukierunkową komunikację pomiędzy modelem a widokiem.
Powyższa składnia zastępuje rozdzielenie atrybutu powiązania zdarzenia czyli () - bananów i danych z modelu, czyli [] - pudełka.
Od dziecka do rodzica
React, co do zasady, zakłada jednokierunkowy przepływ danych. Założenie to wynika ze sposobu zorganizowania architektury komponentowej w aplikacjach React. Nie oznacza to jednak, że nie możemy stworzyć innego rodzaju powiązania danych, gdzie przepływ będzie odwrotny od domyślnego, czyli nie od rodzica do dziecka, a od dziecka do rodzica.
Aby to osiągnąć wykorzystamy ten sam mechanizm, który używamy do tworzenia połączenia jednokierunkowego, a mianowicie propsy. Wystarczy, że zamiast przekazywać wartość do komponentu dziecka, przekażemy callback, który zostanie odpowiednio obsłużony po stronie dziecka. Wówczas zmiana zostanie przekazana w górę drzewa.
Zwróćcie uwagę na powyższą konstrukcję. Komponent dziecka (w tym wypadku ActionButton) wywołuje funkcję, którą otrzymuje z góry z danymi, które chce wprowadzić na poziom komponentu rodzica.
Inne typy wiązań
Warto dodać, że oprócz dwóch wyżej wymienionych, możemy wyróżnić dwa kolejne sposoby wiązania danych, tj. one-way-to-source oraz one-time. Pierwsze z nich jest tak naprawdę odwrotnością wiązania jednokierunkowego, polega na stworzeniu wiązania jednokierunkowego, które działa od widoku do modelu, ale nie na odwrót.
Wiązanie one-time cechuje się tym, że dane na widoku / w aplikacji odbierającej nie są automatycznie aktualizowane. To podejście jest przydatne, gdy potrzebujemy tylko „migawki” (snapshot’a) danych, a same dane są statyczne.
Podsumowanie
Data binding jest techniką dość powszechną. W zasadzie wykorzystywaną na każdym kroku. Przytoczyłem kilka przykładów ze współczesnych aplikacji frontendowych. Prawdopodobnie mógłbym powyższe przykłady rozszerzyć o inne języki, ale wydaje mi się, że powyższe mogą być ciekawe i dają dość szeroki pogląd na to, czym jest data binding.
Pamiętajcie, dbajcie o relacje, nie tylko te prywatne, ale również te pomiędzy poszczególnymi częściami waszej aplikacji.
Komentarze (0)
Jeszcze nikt nic nie napisał, ale to znaczy że... możesz być pierwszy/pierwsza.