w Praktyce
7 godz. 1 min · Angular · Full-stack i Programowanie
Mateusz KuleszaSenior Software Developer, Konsultant, TrenerPodstawą produktywnej pracy z angularem jest możliwość zagwarantowania że wszystko działa bez potrzeby wielokrotnego “przeklikiwania” poszczególnych ekranów. W pierwszej części kursu omawiam więc temat testów automatycznych.Już po obejrzeniu pierwszych lekcji zobaczysz dlaczego warto testować kod i jak dzięki narzędziom dostarczonym z angularem jest to proste. Zobaczysz jak testowanie automatyczne pozwoli zaoszczędzić Ci wiele godzin spędzonych na szukaniu błędów.
Za jakość aplikacji odpowiada nie tylko to czy działa ona poprawnie, ale w dużej mierze decyduje o tym dobry interfejs użytkownika oraz UX, czyli user experience. Dwie kolejne sekcje kursu poświęcone są właśnie dobremu UI oraz UX. Omawiam typowe problemy w oparciu o zasady i wskazówki specyfikacji Google Material Design - jednej z najbardziej szczegółowych specyfikacji UX. Wszystkie przykłady UI zarówno w wariantach desktopowych jak i mobilnych omówione są na przykładzie Angulara oraz obszernej biblioteki komponentów Angular Material. Zobaczysz nie tylko jak korzystając z gotowych komponentów błyskawicznie budować nowe funkcjonalności, ale przy okazji omówimy wiele praktycznych wskazówek oraz dobrych praktyk UX które warto wykorzystać w Twoich aplikacjach.
W ramach budowania interfejsów skupimy się na najmniejszych szczegółach takich jak prawidłowe zachowanie linków, przycisków oraz wskaźników przechodząc stopniowo do coraz większych elementów aplikacji takich jak nawigacja, układ strony, paski nawigacyjne czy okna dialogowe. Przy każdym etapie czeka Cię masa wskazówek, przykładów i rozwiązań typowych problemów user experience.
Jednak UX to nie tylko wygląd i zachowanie pojedynczych elementów. W ostatnich sekcjach kursu dowiesz się jak projektować bardziej złożone interakcje z użytkownikiem. Zobaczysz wieloetapowe formularze kreatora oraz dowiesz się jak zarządzać stanem aplikacji oraz różnymi źródłami danych. Pokaże Ci jak zbudować samodzielnie sortowane, filtrowane i stronicowane źródła danych oraz połączyć je z różnymi komponentami UI takimi jak listy czy datagrid.
Na koniec kursu zobaczysz jak możemy różne gotowe elementy UI połączyć w przepływ ekranów budując ścieżkę użytkownika. Zobaczysz jak prawidłowo zaprojektowane komponenty wraz z dobrze zaplanowanym UX pozwalają być niesamowicie produktywnym jednocześnie nie poświęcając jakości czy dobrej architektury aplikacji.
Jest to kurs dla osób które już pracowały z angularem i chciałyby wyjść poza pojedyncze techniki oraz poznać proces projektowania aplikacji w praktyce z uwzględnieniem najlepszych praktyk programistycznych oraz user experience. Zarówno w wariancie webowym jak i projektując pod urządzenia mobilne.
Angular 6, 7, 8+
Witaj w kolejnej lekcji tym razem zajmiemy się kontrolkami
autopodpowiadania zacznę od tutaj prostego takiego formularza gdzie mamy jedną
kontrolkę i powiedzmy że będzie to służyło do powiedzmy
placeholder do dobierania osób przypisanych
do zadania czyli assign'ing albo po
prostu assign to czyli przypisz zadanie do konkretnej osoby
tutaj powinna się pojawić assign to i chodzi o to że jak będę wpisywał tutaj
jakieś imię nazwisko żeby mi potem wyświetliła
się lista z podpowiedziami do tego wykorzystamy tutaj autocomplete
czyli to jest specjalny moduł w angular material i
jeśli chciałbym żeby taka opcja tutaj zadziałała to umieszczę ją pod spodem pod
inputem no to musimy oczywiście zaimportować odpowiedni moduł czyli
tutaj do naszego modułu mat autocomplete
module okej
to już błędy powinny w takim razie zniknąć i jak będę
pisał tu w inpucie no to chcielibyśmy odpowiednio modyfikować tutaj tablice dostępnych
opcji nazwę to
sugestie i tak tutaj stworzymy sobie w formularzu
mam już przygotowane tutaj jakąś strukturę formularza oprócz tego przygotuję jeszcze tutaj
tablice sugestii no i na przykład tutaj wpiszę sobie alice
bob no
i ktoś tam jeszcze powiedzmy trzy osoby i
teraz jeśli tylko otworzę input chciałam żeby ta lista
się rozwinęła i pokazała mi tutaj w listę dostępnych opcji
do wyboru czyli jeszcze raz w formularzu tutaj mamy autocomplete ten
autocomplete możemy przypisać sobie do jakiejś zmiennej powiedzmy
nazwę to trochę długa
nazwa i tutaj trzeba wydobyć dokładnie tą kontrolkę ze środka nazywać się to
będzie mat to complete
tak i w ten sposób dostajemy się do obiektu autocomplete
który jest zawarty w tym komponencie mat autocomplete i teraz trzeba zawsze
te kontrolki jakoś ze sobą połączyć i w tym celu tutaj do
no właśnie do tej kontrolki musimy podpiąć
ten obiekt który właśnie tutaj wyciągnęliśmy i w tym celu używamy dyrektywy tak
samo będzie się nazwała czyli mat autocomplete
i teraz do tej dyrektywy przy pisze dokładnie tą
referencje którą tutaj sobie pobrałam czyli tutaj haszem wyciągamy to
i przypisujemy tu dyrektywy łączymy te
dwa obiekty ze sobą no i zobaczmy jak to zadziała
tutaj jeszcze mamy widzę literówkę
ok i teraz jak tutaj kliknę to jak widzisz
mamy te wszystkie opcje dostępne jednak chciałbym że jeśli pisze
to w trakcie pisania żeby ta lista mi się filtrowała sortowała
no to w takim wypadku musimy tutaj zareagować na zmianę tego inputa i zaktualizować
listę sugestii żeby ta lista sugestii po prostu się renderowała aktualizowała w
miarę jak pisze teraz moglibyśmy to wszystko zrobić tutaj w tym komponencie
posortować sobie tą tablicę jednak w prawdziwej aplikację jak wiesz ta
lista sugestii może być krótka może być też bardzo długa mogą być to też requesty
na serwer z każdą literką którą w pisze dlatego żeby tutaj nie robić
tego wszystkiego w komponencie stworzymy sobie usługę powiedzmy tutaj mamy usługę
już stworzyłem do wyszukiwania użytkowników tak i tu
zrobimy sobie na przykład find users
find all query all i
tu wpiszemy sobie jakieś hasło jakieś zapytanie string powiedzmy
na początku find all by name na przykład
znajdź po imieniu i teraz nawet żeby nie tworzyć serwera żeby
móc szybko pracować interfejsem no to powiedzmy sobie zamockować dane co to jest mock
mock to jakieś przykładowe dane ja tu mam plik users json takie sobie wygenerowany
z przykładowymi danymi i spróbuję go zaimportować tutaj do tego serwisu
żeby sobie udawał że ściąga z internetu ściąga z serwera to naprawdę prostu będzie
do lokalny plik można bardzo szybko prototypować nowe ekrany nie
martwiąc się no o to że backend o bazy danych
i tak dalej może sobie podłożyć podstawić jakieś tymczasowe sztuczne dane
i teraz żeby to zadziałało tu teraz w configu dodam taką
opcję która pozwoli mi o właśnie
zaimportować json jako moduł
czyli będę mógł dane tutaj zaimportować bezpośrednio do naszego
naszego serwisu tutaj mamy import gwiazdka
jako users from i tu zobaczymy
sobie data users json i teraz ten obiekt users
powinien zawierać wszystkich użytkowników i teraz mogę po prostu
zwrócić tutaj w tej wyszukiwarce tych użytkowników jednak my chcemy zasymulować
udać że te dane są pobierane asynchronicznie z serwera chciałbym
żeby ta funkcja zwracała
observable czyli właśnie wartość asynchroniczną
opakowaną właśnie w observable tu na chwilkę jeszcze otypuję jak ten
nasz użytkownik user ma wyglądać jak spojrzymy sobie na dane
to będziemy potrzbowali id name email position
foto są to pola tego obiektu i tak
samo tu w interfejsie sobie zrobimy żeby to było id number no
a pozostałe tutaj elementy to
będzie string okej
czyli mamy tutaj typ tego obiektu
więc chciałbym żeby ta funkcja find by all zwracała mi tablicę obiektów
typu user tak tutaj to
nie będzie otypowane za chwilkę sobie poradzimy teraz jak to zrobić żeby było observable najprostszym
sposobem jest użycie operatora of tak operator of
zaimportowany z rx js co pozwoli nam tą
wartość którą mamy natychmiast zwrócić opakowaną w observable więc w
przyszłości jak zmienię tą metodę że ona faktycznie robiła metodę http zapytań do serwera no
to wszystkie komponenty nie muszę już ich zmieniać one będą automatycznie odbierały poprawną wartość
ja tylko jeszcze jedną rzecz tych użytkowników postaram się właśnie pofiltrować
posortować żeby one pasowały do tego query czyli
jeśli powiedzmy user name zrobimy go do małych liter żeby duże
małe litery nie miały znaczenia jeśli zawiera to nasze query także
z małej litery jeśli
zawiera to wtedy tylko wtedy załączamy do wyników teraz wywołując tą
metodę powinienem otrzymać natychmiast asynchronicznie ale natychmiast wyniki
tutaj pofiltrowane z tej naszej kolekcji użytkowników wszystkich którym name pasuje
czyli find by name zobaczmy wstrzyknę tą usługę teraz do naszego
komponentu forms extras tu
będzie users service typu
user service angular powinien oczywiście sobie po typie sam wiedzieć
jak wstrzyknąć tą usługę i teraz tutaj dodam
sobie taki jeśli ktoś wprowadzi zmianę w assignee input czyli
this assignee input value changes czyli
jeśli ktoś pisze coś zacznie pisać to byłem tu wykrywamy zmiany
jeśli się zasubskrybuję i wtedy każdą zmianę każdy input użyjemy
do wyszukiwania użytkowników czyli this user service find input
i to nam zwróci tutaj kolejną rzecz muszę zrobić kolejnego subscribe'a no
i teraz żeby nie robić subscribe i drugiego subscribe'a w nim to możemy
zrobić troszkę inaczej zamiast sięsubskrybować na te wartości to tutaj
możemy zrobić coś takiego że użyjemy pipe i
przetransormujemy ten te operacje czyli każda zmiana tutaj
value changes powinna spowodować wywołanie funkcji find by
name i mógłbym zrobić tutaj mat przemapować to na każdą
wartość tak czyli każdy input przemapować sobie
tak w ten sposób oczywiście
operator map trzeba zaimportować z rx js operators tylko
problem jest taki że teraz w inpucie tutaj będę miał observable kolejny będę miał
tutaj zrobię bardzo brzydką rzecz bo musiałbym zrobić w subscribe kolejnego
subscribe'a i w każdej sytuacji gdzie mamy zagnieżdżone observable
możemy pozbyć się tego dodatkowego poziomu gdzie w observable mamy
kolejny observable tak tutaj pobieramy observable zmian i dla
każdej zmiany tworzymy wewnątrz tutaj tego pipe'a kolejny observable
więc żeby to rozpakować zamiast mapa mogę użyć operatora na
przykład switch map który automatycznie
przesubskrybuje się na najnowszy element i wtedy w inpucie mamy już tablice
użytkowników więc mógłbym to wszystko przypisać do
this options i
to teoretycznie powinno suggestions powinno zadziałać tu
jest users tu muszę powiedzieć że jest to typu user
zobaczmy jak wpisze tutaj jakieś litery coś
jeszcze jest nie
tak czemu nam to tego nie podmienia suggestions równa
się input zobaczmy tu jest debuguje czy
to nam zadziała find
all by name nie jest funkcją coś jest nie tak z naszym users service już
zobaczymy find all by name okej
jest user service find all by
name wygląda dobrze jeszcze raz okej
i znalazłem 32 osoby na m jak
teraz puszczę to tu pojawia mi się object object object czyli
działa to aczkolwiek ten nasz html źle wyświetla tych
naszych użytkowników co jeszcze możemy zrobić mogę to przypisywać w ten
sposób jasne robić subscribe wtedy wypadałoby żeby także unsubscribe żeby
tego nie musieć tego subskrybować ręcznie to możemy całą taką operację po prostu
przypisać sobie tutaj do sugestii
i wtedy sugestie będą typu observable user i subskrypcję możemy
zrobić zamiast w javascript'cie możemy tą subskrypcję równie dobrze wykonać od
razu tutaj w htmlu czyli
korzystając z async pipe tutaj w htmlu się
zasubskrybujemy na ten observable który powstał w tym
miejscu czyli wszystkie wyniki tutaj naszego co wpiszemy będzie przetransformowane
zapytania tutaj do naszego poszukiwanego serwera który na prawdę czyta z
pliku i wyniki tu pojawią się w tym observable który
ten async nam rozpakuję do do tej sugestii i teraz tych
opcji chciałem powiedzmy wyciągnąć powiedzmy name i
zobaczmy nie ma żadnych błędów tu
jest jakiś widzę błąd w user service to jeszcze tylko spojrzę sobie
na to user service co tu jest nie tak ok
okej i teraz tak elegancko
pojawia nam się podpowiedzi teraz jeśli
ja spróbuję wybrać którąś z tych osób no to kolejny
problem że teraz ten obiekt trafił do tego naszego pola tutaj
formularza no i co no i jest to
problem bo chcemy wyświetlić tylko name albo tylko jakiś inny identyfikator jeśli
chcemy żeby ten input u góry w przypadku wybrania obiektu wyświetlał tylko
określony sposób formatowany ten obiekt to mamy tutaj możliwość możemy
ustawić sobie może nie w tym miejscu tylko tu na auto complete
możemy ustawić coś takiego jak display with
format powiedzmy tak
sformatuj sugestie sformatuj user
czyli tworzymy sobie funkcję która będzie pozwalała nam formatować odpowiednio te
obiekty do wyświetlenia w inpucie czyli dostajemy tutaj powiedzmy selection
i będzie to albo string który ktoś wpisał albo
już wybrany użytkownik user sprawdzimy
jeśli jest to obiekt tak
czyli jeśli powiedzmy selection
to zwrócimy tylko z tego naszego selection tutaj
widzisz nam od razu skoro wie że to jest obiekt to już nam podpowiada że chcemy name
w przeciwnym wypadku zwrócimy po prostu
selection tak jak jest jeśli jest to string zobaczmy teraz czy
to nam ładnie poformatuje wartości tak
wybieramy coś jeszcze jest nie tak format user suggestion
o mamy niezapisany plik html czyli tutaj musimy zapisać to żeby
on nam wykrył display with tą funkcje
miyah miles okej
i co tu jest jeszcze nie query to lowercase no właśnie jak tu już wybierzemy
obiekt no to on próbuję wtedy wyszukiwać tego przy
użyciu naszej funkcji tutaj szukania czyli zobaczmy jeszcze raz kod tutaj
ten value changes w takim razie może być tu string a może w tym naszym
inpucie pojawić się obiekt więc tutaj trzeba by było sprawdzić może
użyję sobie filter że jak już mamy obiekt to żeby
go nie wyszukiwało zobaczmy
filter zaimportowałem z operatorów i sprawdzimy dokładnie
to samo czyli nie jest to obiektem tak czyli selection jeśli
nie jest obiektem tylko wtedy przepuszczamy zobaczmy
teraz okej
no i teraz tutaj właśnie w tym polu tutaj naszym forms
control pojawi się nam obiekt jeśli pojawi się ten obiekt
i go wybierzemy no to warto było wtedy wpisywać ten obiekt tutaj już nie jako tekst
tylko tutaj jako obiekt przypisać
do tej form control że jest to wybrany użytkownik i jeśli
zobaczymy sobie tutaj html ponownie to tutaj możemy także
dodać sobie różnego rodzaju zdarzenia które
obsługę zdarzeń które występują na tym naszym auto
complecie i tutaj możemy nasłuchiwać na zdarzenie autofill czyli kiedy ktoś
kiedy nam przeglądarka automatycznie powiedzmy wypełni pola możemy to wykryć kiedy jest otwarty
kiedy zamknięty jest podpowiadanie też się może przydać wiedzieć czy ktoś akurat ma otwarty ten panel czy
coś wybiera czy już wybrał no i właśnie jak go wybrał to jest tutaj option selected
dodamy
sobie jakąś funkcję select assignee i przekażemy mu oczywiście zdarzenie które tutaj
wystąpiło ja utworzę tą funkcję w tym miejscu tak
tu powinna być już selection z konkretnym użytkownikiem
którego ktoś chce do zadania przypisać no i
jak mam tego użytkownika no to możemy pod this task tutaj extras
assignee właściwie tutaj
pobierz pole assignee czyli tutaj próbuję dać się do tego miejsca i
ustalimy to selection tylko set value okej
selection i żeby
zobaczyć czy wszystko działa ja tutaj podejrzę sobie całą strukturę tego formularza czyli
pod spodem tutaj w preformatowanym polu wyświetlimy
sobie task extras value czyli
wartość całego tego tutaj pola formularza zobaczymy czy nam się tutaj
użytkownik pojawi w środku w tym elemencie object
object już coś tam jest zobaczymy tutaj jak zrobimy json żeby
to troszkę więcej wiedzieć o tym obiekcie mamy assignee null
czyli nikt nie jest przypisany do naszego zadania wpiszemy sobie mia
i coś poszło tu jeszcze nie tak no
tak on próbuje skonwertować teraz złożony cykliczny obiekt do
stringa czyli tutaj to nie jest
zwykły selection tak naprawdę option selected zerknijmy do dokumentacji
jest to bardzo skomplikowany obiekt zobaczmy tutaj zdarzenia custom
input element okej
zobaczmy sobie w dokumentacji to zdarzenie
tutaj może
tu będzie w api jak wygląda struktura tego
event'a czyli zdarzenia okej
jest to mat-autocomplete selected event no to
zaimportujmy sobie ten typ i zobaczymy co to będzie czyli tutaj jak ktoś coś wybierze to
będzie to zdarzenie tego typu czyli
z tego selection musimy pobrać jeszcze option albo source czyli
mamy dostęp do całego auto complete'a albo do wybranej opcji my chcemy opcję
gdybyśmy chcieli cały auto complete to
tutaj możemy pobrać informacje dokładnie wszystko na temat tego elementu
czy jest otwarte jakie ma opcje która opcja jest zaznaczona panel
i tak czyli możemy tu nie tylko dostać informację co zostało zaznaczone ale także wpłynąć
na ten element może zostawić otwarte zamknąć zwinąć zaznaczyć
i tak dalej czyli tym razem powinno być to okej powinniśmy zostawić tutaj opcję konkretną
zobaczmy wybraną nikt nie jest zaznaczony wpiszemy sobie coś tam wybieramy
sobie michelle jeszcze coś tu jest nie tak dalej
próbuje mi cykliczną strukturę przypisać dlaczego zbadajmy to
tutaj debuggerem okej
co tu dostajemy selection option no
właśnie jest to cała opcja a my chcemy tylko value czyli
trzeba wiedzieć jeszcze trzeba jeszcze głębiej jak widzicie się dostać czyli
option to jeszcze jest dopiero jedna opcja wybrana tu masz zaznaczone
czy aktywna i tak dalej nas interesuje etykieta
grupa id i
możemy też zaznaczyć opcję odznaczyć czyli mamy pełną kontrolę
nad tym co się dzieje nas interesuje value
mamy wartość wyświetlaną czyli tą zwróconą z funkcji format
albo faktyczną wartość od całego obiektu item value to
powinien być nasz user
dobra zobaczymy teraz
trzeba dokładnie wybrać to co jest potrzebne z tego autocomplete'a okej
mia i ładnie jako assign tutaj czyli przypisana osoba mamy cały obiekt włącznie
z id name email position i tak dalej czyli nam formularzu pojawił cały obiekt
czyli jak widzisz wartościami pola formularzy nie muszą być też stringi liczby tutaj wartością kontrolki
może być cały obiekt czyli tu wybieramy albo string albo obiekt i dopiero jak mamy wybraną opcję
to z tego takiego pomocniczego pola tymczasowego przepisujemy do
tego właściwego pola formularza które moglibyśmy zserializować
wysłać na serwer okej to tyle jeśli chodzi o auto complete
jak widzisz tu dużo możliwości mamy też pełną kontrolę nad tym co się dzieje tak czyli autocomplete
tylko nas poinformuje że ktoś coś pisze albo ktoś coś wybrał logikę musimy
sami napisać ma to jednak tą korzyść zaletę że jesteśmy ograniczeni już
jakimś gotowym zachowaniem tylko możemy tutaj w pełni wpłynąć na to co się dzieje na
tak już wybierak to się zaznaczenie nie dostajemy tylko opcji wyboru ale
cały auto complete wszystkie opcje całą kontrolkę możemy
dokładnie w różne sposoby jak chcemy zareagować na to czy
ktoś coś wybrał w naszym autocomplete'cie okej to tyle jeśli chodzi o auto-complete
i do zobaczenia w kolejnej lekcji