[PL] Kurs Angular na Steemit #2 /Na początku był chaos/

in #polish6 years ago (edited)

// for my non-polish readers: this is just a polish translation of this article

Celem tego artykułu jest przekazanie wiedzy oraz jej źródeł, które pozwolą Ci rozpocząć tworzenie prostych aplikacji, z których kodem nikt prawdopodobnie nie będzie chciał pracować. Nie, nie jestem pijany.

Poczekaj, co?

No może nie jest to najlepszy opis intencji, którymi się kierowałem. Tak, ten tutorial nie uczyni Cię mistrzem Angulara, który będzie pisał kod najwyższej jakości, ale zdecydowanie ten wpis wraz z dołączonymi linkami powinien powinien dostarczyć wystarczającą widzę aby zacząć bawić się Angularem oraz Firestore (jeśli nie czytałeś poprzedniej części kursu, zachęcam do zrobienia tego teraz). Głębsze wytłumaczenie koncepcji z grubsza opisanych teraz znajdzie się w kolejnych wpisach.

Właśnie, linki. Nie da się ukryć, że najpopularniejszym językiem w IT jest język angielski. Nie chcę teraz się o tym rozpisywać, ale efektem tego jest to, że artykuły, prelekcje i dokumentacje, które polecam sprawdzić po przeczytaniu tego artykułu, są po angielsku. Nie da się tego przeskoczyć.

Jednak zanim przejdziemy do kodu projektu aplikacji zarządzającej zadaniami, musimy przyjrzeć się językowi programowania, którego będziemy używać.

TypeScript

Ale jak to, w wymaganiach do tego kursu była znajomość JavaScript, a ty mi wyskakujesz z jakimś TypeScript
każdy

Czym jest TypeScript?

Wystarczy o tym myśleć jak o potężniejszym JavaScripcie. Na koniec i tak się kompiluje do JSa, ponieważ jest tylko jego nadzbiorem. Czemu więc powinniśmy tego używać? Najważniejszą różnicą jest to, że TS jest silnie typowany, czyli możemy określić typ (string, number, itp.) zmiennej lub tego, co ma być zwrócone z funkcji przy ich deklaracji. Jest to jednak opcjonalne, nic nie stoi na przeszkodzie, aby wciąż używać dynamicznego typowania, ale stracimy wtedy możliwość unikania pewnych błędów jeszcze podczas pisania kodu... i Angular team używa TypeScript wraz z silnym typowaniem ;)

Jakie elementy TypeScript powinieneś znać?

Będę teraz szczery - jest ich mało. TS sam w sobie jest bardzo potężnym narzędziem, ale w tym kursie będziemy używać tylko paru jego elementów. Pozostały kod to tak naprawdę JavaScript (w tym najnowsze wersje ES6 i ES7, tak, kompilator TypeScript radzi sobie również z nimi).

Co więc powinieneś potrafić?

  • typy
    jak już wcześniej wspomniałem, w TS możemy deklarować zmienne i funkcje określając jednocześnie ich typ, na przykład jeśli chcemy aby zmienna numberOfTasks była liczbą, możemy jej używać w następujący sposób:
  • klasy
    właśnie z nich zbudowana jest większość elementów Angulara, których będziemy używać. Okazuje się, że klasy w TS działają analogicznie do tych znanych z innych języków programowania, jak np. C#. Są one dodatkowo bardzo podobne do klas znanych ze składni ES6, jednak wprowadzają dodatkowo obsługę modyfikatorów dostępu (domyślnie public, można też używać private oraz protected, po więcej informacji zapraszam oczywiście do sekcji linków).

    jest parę sztuczek, których będziemy używać, na przykład zamiast pisać konstruktor taki jak na przykładzie powyżej, możemy zapisać go skrótem:

    taki konstruktor utworzy właściwość publiczną klasy name oraz przypisze do niej wartość otrzymaną przy inicjalizacji obiektu na podstawie tej klasy.
  • interfejsy
    silne typowanie jest świetnym narzędziem, ale co jeśli zmienna ma być obiektem określonego typu? Możemy w takiej sytuacji zdefiniować interfejs:

    interfejsy są ograniczone w stosunku do klas, nie można ich na przykład zainicjalizować (za pomocą słowa kluczowego new), nie mogą implementować logiki. Dlaczego jednak powinniśmy ich używać? Ponownie, zapraszam do zapoznania się z sekcją linków.

Podstawowe elementy Angulara

Spójrzmy na strukturę plików projektu (kod jest dostępny Githubie):

Całkiem sporo plików i folderów, co? Mam dla Ciebie dobrą wiadomość - większością nie musisz się przejmować (przynajmniej na tym etapie nauki). To, czego potrzebujesz znajduje się w folderze src:

  • jaki jest pierwszy plik serwowany klientowi odwiedzającemu stronę internetową? Tak, index.html:

    jednak jako użytkownicy Angular CLI możemy usiąść pod palmą i cieszyć się tworzeniem logiki i widoków aplikacji bez większych zmartwień o ten plik - CLI doda tu wszystkie potrzebne pliki w czasie budowania projektu.
  • nie będziesz pewnie zdziwiony również, jeśli powiem, że flik styles.scss definiuje style naszej aplikacji. Należy jednak pamiętać, że są to style globalne:

    różnica między tymi stylami a stylami lokalnymi będzie dla Ciebie intuicyjna, gdy przedstawię komponenty
  • kolejnym plikiem kluczowym dla CLI i dosyć bezużytecznym dla nowicjusza jestmain.ts:

    jest to punkt początkowy aplikacji. Ładuje on moduł główny (AppModule) projektu. Zazwyczaj nie musisz tu nic zmieniać.
  • assets jest folderem, w którym powinieneś przechowywać takie pliki, które podczas budowania projektu mają zostać w takim stanie, w jakim są, np. obrazki
  • environments to folder, w którym przechowujemy zmienne konfiguracyjne, takie jak np. firebaseConfig który dodaliśmy w poprzedniej części kursu
  • app jest folderem, w którym będziemy wykonywać główną część naszej pracy. Zawiera wszystkie moduły, komponenty, serwisy, dyrektywy, pipe'y, itd. Będziemy mieć tu sporo zabawy.

Komponenty


Komponent jest elementem Angulara, którego będziesz używać najczęściej. Upraszczając, odpowiadają one za część aplikacji, której zadaniem jest kontrola widoków, czyli interakcji z użytkownikiem.

Każdy komponent składa się z następujących elementów:

  • dekorator @Component() - jest używany aby poinformować kompilator, że klasa następująca po nim jest komponentem. Przyjmuje on pewne opcje konfiguracyjne, np:
    • selector - ta opcja określa znacznik, jaki będzie miał ten komponent. Selector w naszym AppComponent to app-root, więc kiedykolwiek Angular znajdzie <app-root></app-root> w szablonie komponentu, który jest wyżej w drzewku komponentów (tzn. jest przynajmniej jego rodzicem), dodaje w to miejsce AppComponent. Już widzieliśmy ten znacznik - w index.html. Dokładnie, AppComponent jest głównym komponentem (najwyższy w drzewku) naszej aplikacji, więc gdy będziemy w przyszłości dodawać inne komponenty, to właśnie w jego szablonie będziemy umieszczać ich znacznik.
    • templateUrl - ścieżka do szablonu komponentu, można zamiast tego użyć template i szablon umieszczać bezpośrednio w pliku .ts, jednak wtedy kod może stać się nieczytelny
    • styleUrls - lista ścieżek do plików .scss komponentu (style lokalne)
  • export class ComponentNameComponent {} - tu umieszczasz logikę komponentu. Możesz tu robić wszystko to, co umożliwia TypeScript. Dodatkowo zarówno metody jak i właściwości tu zdefiniowane mogą być użyte przez szablon komponentu

Używanie komponentu bez szablonu nie miałoby zbyt dużego sensu, to tu dzieje się magia:

Przepływ danych

Wymiana informacji pomiędzy aplikacją a użytkownikiem (i w przeciwną stronę) jest kluczowa w nowoczesnych aplikacjach internetowych. Jak jest osiągana w Angularze? Jestna to pare sposobów:

  • wyświetlanie danych (z klasy do szablonu):
    powiedzmy, że mamy zmienną name w klasie komponentu. Aby wyświetlić jej wartość w szablonie wystarczy dodać w dowolnym miejscu szablonu {{ name }} (jest to nazywane string interpolation), a Angular znajdzie odpowiednią właściwość w klasie i zastąpi to miejsce jej wartością.
  • property binding (z klasy do szablonu):
    a co jeśli chcielibyśmy, aby np. dany element HTML w szablonie wyświetlał się tylko gdy właściwość display w klasie komponentu ma wartość true? Jedną z możliwości jest modyfikowanie właściwości hiddenelementu HTML, ale jak ją powiązać ze zmienną z klasy? Angular sprawia, że jest to proste:
    <jakis-element [hidden]="display">Jeśli display to false, nie będzie mnie widać!</jakis-element>
    Możemy w ten sposób działać nie tylko na natywnych elementach HTML, ale także na dyrektywach.
  • event binding (z szablonu do klasy):
    obie powyższe metody pozwalały na przepływ danych w jedną stronę, od klasy do szablonu. Aby przekazywać dane w odwrotną stronę, czyli od użytkownika do aplikacji, możemy użyć event bindingu
    <button (click)="deleteAccount('jakipatryk')">Usuń konto</ button>
    w powyższym przykładzie wywołujemy metodę deleteAccount() i przekazujemy jej wartość "jakipatryk" za każdym razem, gdy użytkownik kliknie ten przycisk
  • two-way data binding
    zdarza się, że chcemy połączyć przepływ danych w obie strony, możemy to zrobić na skróty:

    okazuje się, że podczas wpisywania przez czegokolwiek w input z powyżeszego przykładu, aktualizowana jest także wartość w miejscu {{itemName}}.

Dyrektywa *ngFor

Załóżmy, że masz tablicę itemsArray składającą się z obiektów typu Item. Każdy jej element ma właściwości name i type. Jak to wyświetlić w szablonie komponentu w prosty sposób? Dzięki wbudowanej dyrektywie NgFor jest to możliwe:

jak widzisz, iterujemy po tablicy itemsArray i nazywamy każdy jej element item. Angular wyrenderuje tyle div'ów ile jest elementów w tablicy i wypełni każdy z nich danymi danego elementu używając string interpolation.

Serwisy

Component classes should be lean. They don't fetch data from the server, validate user input, or log directly to the console. They delegate such tasks to services.
źródło: dokumentacja Angulara

Serwisy są bardzo ważne. Teoretycznie większość tego, co tam się pisze, może być napisane w klasie komponentu. Jest to jednak podejście bardzo ograniczone. Angular używa pewnej techniki, znanej jako dependency injection (wstrzykiwanie zależności) aby przekazać komponentom instancje serwisu, jakiej potrzebują.

W serwisy i technikę dependency injection zagłębimy się w następnej części kursu.

Moduły

Zdaje się, że już słyszałeś o Angularowych modułach (nie mylić z JavaScriptowymi) - w pliku main.ts zdefiniowany jest moduł główny projektu - moduł, który jest ładowany na starcie aplikacji. Naszym głównym modułem jest oczywiście AppModule:

Dekorator @NgModule() także przyjmuje pewne opcje konfiguracyjne:

  • declarations - umieszczane są tutaj wszystkie komponenty, napisane przez nas dyrektywy i pipe'y, których będziemy chcieli użyć w obrębie tego modułu (zasięg modułów będzie opisany w dalszej części kursu)
  • imports - jeśli dany moduł potrzebuje do działania innego modułu, np. jego serwisów bądź komponentów, tutaj właśnie go dodajemy
  • providers - brzmi jak świetne miejsce do umieszczania serwisów (no nie zawsze, ale zazwyczaj tak, więcej o tym w następnym wpisie)
  • bootstrap - Angular powinien wiedzieć, który komponent jest tym głównym w danym module, a to jest całkiem dobre miejsce aby go określić

Dodawanie tego wszystkiego ręcznie byłoby zdecydowanie męczące, a programista nie lubi się męczyć. Całe szczęście, że mamy Angular CLI, który prawidłowo używany po raz kolejny zaoszczędzi nam mnóstwo czasu. Musisz jednak uważać. Jeśli generujesz za pomocą CLI np. komponent, to jest on automatycznie dodawany do AppModule (gdy mamy więcej niż jeden moduł nie koniecznie chcemy dodawać go akurat do AppModule), a jeśli generujemy serwis, domyślnie nie jest on nigdzie dodawany, więc musimy albo dodać go ręcznie albo zastosować flagę --module ModułDoKtóregoChcemyDodaćSerwis gdy go generujemy.

W tym momencie mamy tylko jeden moduł, ale gdy projekt staje się bardziej rozbudowany należy nastanowić się nad zmianą tej architektury, ponieważ moduły dają nam potężne narzędzia do organizacji proejktu i nie tylko. Ale o tym kiedy idziej.

AngularFire2

Tak właściwie to więcej kodu już dziś nie będzie. Jednak nawet jeśli by zastosować taktykę kopiuj-wklej z Githuba projektu, aplikacja by nie działała. Musimy jeszcze wykonać parę czynności. Po pierwsze musimy zainstalowć poniższe zależności:
npm install angularfire2 firebase --save
AngularFire2 to oficjalna biblioteka do używania Firebase w Angularze. Jeśli czytałeś kod z TaskService to mogłeś zauważyć, że ta biblioteka jest tam używana - wszystkie operacje na Firestore są tam właśnie przez nią obsługiwane.

No to teraz mamy zależności, ale... nie mamy bazy danych (Firestore). Należy więc ją utworzyć:

  1. Otwórz konsolę Firebase i wejdź do swojego projektu.
  2. Nawiguj do Database.
  3. Kliknij TRY FIRESTORE BETA:
  4. Wybierz Start in test mode i kliknij enable:

Jesteśmy już blisko końca. Spróbuj zaserwować projekt (ng serve). Twoim oczom ukaże się piękny czerwony błąd w konsoli:

Na szczęście AngularFire2 ma odpowiednie narzędzia do obsługi tego błedu i jedyne co musimy zrobić to kliknąć na link zawarty w komunikacje błędu i kliknąć "CREATE INDEX":

Podsumowanie

W tej części kursu Angulara przedstawiłem podstawy takich technologii jak TypeScript, Angular i Firestore, które zostały użyte do zbudowania prostej aplikacji do zarządzania listą zadań, która będzie w trakcie tego kursu rozwijana:

wszystkie taski synchronizują się z Google Cloud Firestore:

Po przeczytaniu tego wpisu oraz treści zawartych w polecanych linkach, nie powinno być problemu z wykonaniem małych zmian w aplikacji kursowej lub nawet z utworzeniem prostej aplikacji od podstaw.

Linki, które warto sprawdzić:


Sort:  

Od początku rzucasz nas na głębokie wody :) Udało mi się zrobić wszystko to co jest konieczne do działania, ale nadal jeszcze nie rozumiem dlaczego to działa. Chyba muszę zatrzymać się z tą częścią kursu na dłużej, aby to zrozumieć.

W następnych częściach będę starał się wytłumaczyć co się dzieje w tym kodzie, na ten moment nie musisz tego wszystkiego rozumieć.

Oczywiście warto starać się samemu to ogarnąć (teoretycznie w dołączonych linkach jest wszystko czego potrzeba, ale rzeczywiście jest to ogrom materiału jak na początek). Jednak następna część za ok. 2 tygodnie, więc jest troszkę czasu na sprawdzenie ;)

Dla mnie niezrozumiałe, ale daję upvotea ze względu na markę konta jakipartyk.

Coin Marketplace

STEEM 0.26
TRX 0.11
JST 0.032
BTC 63754.85
ETH 3055.95
USDT 1.00
SBD 3.85