Atrybut funkcyjny jest atrybutem o nieco innej charakterystyce w porównaniu do atrybutów przedstawionych w poprzednich rozdziałach.
Jego działanie polega na przekazaniu do dyrektywy funkcji, której uruchomienie spowoduje wykonanie kodu znajdującego się w komponencie nadrzędnym.
Korzystając z tego atrybutu możemy więc sterować zachowaniem komponentu nadrzędnego (parenta) z poziomu komponentu podrzędnego (dyrektywy),
co daje nam całkiem nowe możliwości w kontekście przetwarzania danych w aplikacji.
Atrybut dopasowujący '&' oraz '&attr'
Atrybuty są do siebie podobne na wzór tego jak podobne są do siebie atrybuty '=' i '=attr' oraz '@' i '@attr'.
Dokładniej rzecz ujmując różnica pomiędzy nimi polega na tym, że w przypadku atrybutu '&attr' podajmy inną nazwę dla atrybutu, a inną nazwę
określamy w ramach dyrektywy. Pozostałe funkcjonalności pozostają bez zmian, stąd też skupimy się tutaj na przedstawieniu ich działania
korzystając tylko i wyłącznie z atrybutu '&'.
Wiemy już, ze atrybut '&' pozwala nam na przekazanie funkcji do dyrektywy, aby w ten sposób dać możliwość uruchomienia funkcji komponentu nadrzędnego
z poziomu komonentu podrzędnego, czyli właśnie z tej dyrektywy. Uruchamiając funkcję możemy dodatkowo przekazać parametry do jej ciała, co pozwala nam na
jeszcze większą interakcję z danymi znajdującymi się w komponencie parenta (zarządzanego przez kontroler).
Tworzymy więc kontroler z naszą funkcją:
a wraz z nim dyrektywę z atrybutem
&:
Następnie w ramach HTML-a dyrektywy możemy odwołać się do naszej funkcji, tak jak w poniższym fragmencie:
Teraz aby takie rozwiązanie zadziałało, musimy podać w naszym atrybucie
somefunc nazwę funkcji przygotowanej w kontrolerze:
W rezultacie dyrektywa pojawi się w przeglądarce w postaci HTML-a zawierającego link "Show item info!", którego kliknięcie wywoła funkcję w kontrolerze (wyświetlającą alert box).
W tym przykładzie ciało funkcji wykonuje banalną operację wyświetlenia komunikatu, jednak nic nie stoi na przeszkodzie, aby funkcja ta
wykonywała bardziej zaawansowane operacje. Mogłaby np. modyfikować dane przechowywane w kontrolerze w postaci listy.
W takim przypadku dodawanie lub usuwanie obiektu z tej listy wykonywane byłoby z poziomu dyrektywy.
Rekomendacja
Funkcjonalność, którą otrzymujemy dzięki atrybutom funkcyjnym jest naprawdę potężnym narzędziem,
które z jednej strony daje nam duże możliwości w kontekście pracy z danymi na wielu poziomach, a z drugiej powoduje że jego użycie
może stać się niebezpieczne jeśli chodzi o zachowanie kontroli nad algorytmami w aplikacji.
Nadmierne korzystanie z atrybutów funkcyjnych
doprowadza bardzo często do bałaganu w aplikacji, gdyż zmieniając kod dyrektywy bardzo łatwo jest wpłynąć na zmianę komponentu, do którego ta dyrektywa została wstawiona.
Jeśli do tego owa dyrektywa jest używana w wielu miejscach w aplikacji to kłopot gotowy. Warto więc po takich zmianach poświęcić trochę czasu na dodatkowe testy.
W naszych projektach atrybutu funkcyjnego używamy relatywnie rzadko. Przydaje się on na przykład w trakcie tworzenia dyrektyw zwracających do kontrolera
dane, które ten kontroler zbiera i wykorzystuje później w szerszym kontekście. Wtedy część zbierania danych może być wykonywana na różne sposoby, przez różne dyrektywy,
w wyniku czego kontroler nie musi zajmować się pobieraniem danych oraz ich aktualizacją. Skupia się jedynie na ich przetwarzaniu.
Używamy w StartAPPa
Atrybutu funkcyjnego nie używamy w naszych kursach, dlatego też podaliśmy tutaj pełny i nieskomplikowany przykład użycia takiego atrybutu.
Możecie go w łatwy sposób podpiąć do dowolonego modułu ściągniętego w ramach kursów, co pozwoli Wam przetestować go w praktyce oraz umożliwi dalsze ćwiczenia w ramach tego tematu.
Linki:
https://docs.angularjs.org/api/ng/service/$compile#directive-definition-object