Darmowy fragment publikacji:
Tytuł oryginału: Building Web Apps with Ember.js
Tłumaczenie: Andrzej Stefański
ISBN: 978-83-283-0610-3
© 2015 Helion S.A.
Authorized Polish translation of the English edition Building Web Apps with Ember.js,
ISBN 9781449370923 © 2014 Jesse Cravens and Thomas Q Brady.
This translation is published and sold by permission of O’Reilly Media, Inc., which owns or
controls all rights to publish and sell the same.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by
any means, electronic or mechanical, including photocopying, recording or by any
information storage retrieval system, without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu
niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą
kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym,
magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź
towarowymi ich właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce
informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich
wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub
autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności
za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Pliki z przykładami omawianymi w książce można znaleźć pod adresem:
ftp://ftp.helion.pl/przyklady/emberw.zip
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/emberw
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis tre(cid:316)ci
Wst(cid:253)p ............................................................................................... 7
1. Wprowadzenie do Ember.js
Ergonomia dewelopera?
Czym jest ORM?
Czym jest Ruby on Rails?
Czym jest Node.js?
Wymagaj(cid:241)ce aplikacje internetowe nie s(cid:241) dokumentami
Stan w wymagaj(cid:241)cych aplikacjach internetowych
D(cid:228)ugi czas dzia(cid:228)ania wymagaj(cid:241)cych aplikacji internetowych
Wymagaj(cid:241)ce aplikacje internetowe maj(cid:241) architektur(cid:246)
i wymagaj(cid:233)cych aplikacji internetowych ..................................... 15
16
Czym jest „wymagaj(cid:241)ca aplikacja internetowa”?
16
17
19
21
23
24
24
25
25
26
26
2. Podstawy ....................................................................................... 27
27
30
32
34
35
36
39
3. Szkielet aplikacji i praca nad kodem z Ember ............................... 41
43
45
45
Witaj, WWW
SimpleHTTPServer (cid:127) naprawd(cid:246) prosty
(cid:227)(cid:241)czenie danych
Ale gdzie znajduje si(cid:246) ca(cid:228)y kod?
Co to takiego ten router?
Dzia(cid:228)anie Ember
Podsumowanie
Git
Czym jest Yeoman?
Instalowanie Yeoman
Czym jest Ember.js?
Dlaczego warto wybra(cid:232) Ember?
Express.js
3
Kup książkęPoleć książkęKorzystanie z generatora aplikacji Ember z Yo
Instalowanie wykorzystywanych narz(cid:246)dzi
Instalowanie generatora
Uruchamianie generatora
Wykorzystanie mened(cid:276)era pakietów Bower
Grunt
Kompilacja, uruchomienie, testowanie
46
46
47
48
53
54
55
Debugowanie z Ember Inspector
w przegl(cid:241)darkach Chrome i Firefox
Podsumowanie
Rock’n’Roll
Zaczynamy od HTML
Podstawy Handlebars.js
Zmienne
Tworzenie odno(cid:264)ników za pomoc(cid:241) {{link-to}}
Wprowadzanie danych z {{input}}
Listy z {{each}}
Warunki ze znacznikami {{if}} oraz {{else}}
Obs(cid:228)uga dzia(cid:228)a(cid:254) u(cid:276)ytkownika za pomoc(cid:241) {{action}}
Powi(cid:241)zane atrybuty
Tworzenie w(cid:228)asnych znaczników
Podsumowanie
57
63
4. Prototyp aplikacji Rock’n’Roll Call: szablony ...............................65
65
68
69
72
73
74
77
79
80
81
83
86
5. Prototyp aplikacji Rock’n’Roll Call: router, (cid:316)cie(cid:348)ki i modele ........87
88
90
92
96
97
99
101
102
105
URL — internetowy odpowiednik „kodu do poziomu”
Routing
Router
Dynamiczne (cid:264)cie(cid:276)ki
(cid:263)cie(cid:276)ki
Modele
Obietnice, obietnice
Metoda model()
Podsumowanie
6. Prototyp aplikacji Rock’n’Roll Call: kontrolery, widoki,
po(cid:293)(cid:233)czenia z danymi i zdarzenia ................................................. 107
108
Kontrolery
Generowane w(cid:228)a(cid:264)ciwo(cid:264)ci
111
4
(cid:95)
Spis tre(cid:316)ci
Kup książkęPoleć książkęPot(cid:246)ga obietnic i metoda model
Widoki
Podsumowanie
Ember Data
Ember Model
Ember RESTless
Ember Persistence Foundation
Nie wymy(cid:264)lajmy Ajaksa na nowo
Musi by(cid:232) lepszy sposób
Biblioteki Ember do zapisywania danych po stronie klienta
113
120
122
7. Zapisywanie danych .................................................................... 123
123
126
126
126
127
127
127
127
128
129
130
134
134
135
135
141
8. Przygotowanie cz(cid:253)(cid:316)ci serwerowej ............................................. 143
144
144
Tworzenie routera, widoku i stanu dla aktywno(cid:264)ci
Modele
Zapisywanie danych wyszukiwanych przez u(cid:276)ytkownika
Skok na g(cid:228)(cid:246)bok(cid:241) wod(cid:246) z Ember Data
145
150
150
151
151
153
153
154
156
157
163
Spis tre(cid:316)ci
(cid:95)
5
Warstwy abstrakcji: magazyn, serializacja i adaptery
Ember Data Store
Serializer
Adaptery
Podsumowanie
REST-owe API us(cid:228)ug sieciowych
Ember Data RESTAdapter
Tworzenie makiet API EAK (Ember App Kit)
za pomoc(cid:241) Express.js
Po co korzysta(cid:232) z Rails?
Zarz(cid:241)dzanie zale(cid:276)no(cid:264)ciami:
RVM (Ruby Version Manager) i Bundler
Instalacja Rails
Generowanie aplikacji startowej
Aktualizacja Gemfile
Usuwanie TurboLinks
Dzia(cid:228)anie jednostronicowej aplikacji z Rails MVC
Testy
Dodanie Ember
Podsumowanie
Kup książkęPoleć książkęAnatomia komponentu Ember
Testowanie Ember z Ember App Kit, Qunit i Testem
Mechanizmy uruchamiaj(cid:241)ce testy Testem i Qunit
Testy integracyjne Ember po stronie klienta
Tworzenie szablonu
Rozszerzanie Ember.Component
Tworzenie wizualizacji za pomoc(cid:241) mapy termicznej z D3
9. Komponenty Ember ..................................................................... 165
166
166
168
169
173
10. Testowanie Ember ....................................................................... 175
176
179
181
181
182
183
187
189
190
191
192
193
Podsumowanie
Skorowidz .................................................................................... 195
Podsumowanie
Funkcje pomocnicze
Testowanie strony g(cid:228)ównej
Testowanie (cid:264)cie(cid:276)ki Activities
Testy jednostkowe Ember
Wykorzystanie Ember-Qunit
Testy jednostkowe (cid:264)cie(cid:276)ek
Korzystanie z FIXTURES
Testy jednostkowe modeli
6
(cid:95)
Spis tre(cid:316)ci
Kup książkęPoleć książkęROZDZIA(cid:292) 4.
Prototyp aplikacji
Rock’n’Roll Call: szablony
W rozdziale 3. poznali(cid:264)my nowoczesne narz(cid:246)dzia wspomagaj(cid:241)ce prac(cid:246) przy
przygotowywaniu szkieletu z(cid:228)o(cid:276)onej aplikacji internetowej. Gdy mamy ju(cid:276)
dobrze opanowane podstawy, nadszed(cid:228) czas, by zacz(cid:241)(cid:232) pisa(cid:232) kod.
W tym rozdziale skupimy si(cid:246) na systemie do obs(cid:228)ugi szablonów — Han-
dlebars.js — który domy(cid:264)lnie jest do(cid:228)(cid:241)czany do aplikacji z frameworkiem
Ember. Zwykle nie(cid:228)atwo jest ustali(cid:232), od czego powinno si(cid:246) zaczyna(cid:232) oma-
wianie tego typu systemu, z wieloma zale(cid:276)nymi od siebie „kurami” i „jajka-
mi”. My zdecydowali(cid:264)my si(cid:246) rozpocz(cid:241)(cid:232) od szablonów, poniewa(cid:276) naszym
zdaniem od tego powiniene(cid:264) zaczyna(cid:232) tworzenie ambitnego projektu. Po
tym, gdy przewrócisz ostatni(cid:241) stron(cid:246) tego rozdzia(cid:228)u, b(cid:246)dziesz wiedzia(cid:228),
jak wprowadzi(cid:232) „(cid:276)ywe” (powi(cid:241)zane dwustronnie) zmienne do szablonu
HTML, jak automatycznie generowa(cid:232) (i aktualizowa(cid:232)) listy HTML (znacz-
niki UL i OL) z referencji do tablic, a nawet jak wykorzystywa(cid:232) w swoich
szablonach konstrukcje logiczne (if/then/else).
Rock’n’Roll
Gdy pojawia si(cid:246) potrzeba napisania aplikacji demonstruj(cid:241)cej nowy framework
lub nowy sposób pisania aplikacji, okazuje si(cid:246), (cid:276)e jedynym chyba rozwi(cid:241)-
zaniem jest napisanie aplikacji do zarz(cid:241)dzania list(cid:241) zada(cid:254). Zastanawiali-
(cid:264)my si(cid:246), czy ma na to wp(cid:228)yw atmosfera w Dolinie Krzemowej. Mieszkamy
w Austin w Teksasie, w okolicy czasem nazywanej Krzemowymi Wzgó-
rzami — okre(cid:264)lenie to jest pochodn(cid:241) du(cid:276)ej ilo(cid:264)ci firm technologicznych,
które cz(cid:246)(cid:264)ciowo lub w ca(cid:228)o(cid:264)ci przenios(cid:228)y tu swoje biura z Kalifornii. Firmy
65
Kup książkęPoleć książkęte umiejscowi(cid:228)y si(cid:246) tutaj z wielu powodów, mi(cid:246)dzy innymi dla du(cid:276)o ta(cid:254)-
szej ziemi i si(cid:228)y roboczej, ale nie mo(cid:276)emy si(cid:246) oprze(cid:232) wra(cid:276)eniu, (cid:276)e znaczenie
mia(cid:228)o równie(cid:276) tempo (cid:276)ycia. Aby zademonstrowa(cid:232) swoje nastawienie, posta-
nowili(cid:264)my, (cid:276)e nasza przyk(cid:228)adowa aplikacja nie b(cid:246)dzie dotyczy(cid:228)a produktyw-
no(cid:264)ci. Zbudujemy co(cid:264) w stylu The Internet Movie Database (imdb.com), ale
w celu indeksowania zespo(cid:228)ów i muzyków, a nie filmów, re(cid:276)yserów i akto-
rów. Aplikacj(cid:246) t(cid:246) nazwiemy Rock’n’Roll Call. A niezale(cid:276)nie od niej istnieje
ju(cid:276) wspania(cid:228)a aplikacja demonstracyjna Ember, obs(cid:228)uguj(cid:241)ca list(cid:246) rzeczy do
zrobienia na portalu TodoMVC, któr(cid:241) mo(cid:276)na zobaczy(cid:232) pod adresem
http://todomvc.com/examples/emberjs.
Aby tego typu aplikacja by(cid:228)a u(cid:276)yteczna, musi obs(cid:228)ugiwa(cid:232) co najmniej po-
ni(cid:276)sze opcje:
U(cid:276)ytkownik musi mie(cid:232) mo(cid:276)liwo(cid:264)(cid:232) wyszukiwania artystów (utworów)
po nazwie (tytule).
W idealnym przypadku nie powinno by(cid:232) konieczne okre(cid:264)lanie, czy
szuka si(cid:246) artysty, czy utworu; u(cid:276)ytkownik powinien mie(cid:232) mo(cid:276)liwo(cid:264)(cid:232)
wpisania szukanego terminu i klikni(cid:246)cia Szukaj.
Wyniki wyszukiwania powinny by(cid:232) wy(cid:264)wietlane z oznaczeniami,
jakiego typu element (artysta czy utwór) zosta(cid:228) odnaleziony.
Nie chcemy k(cid:228)opota(cid:232) u(cid:276)ytkowników konieczno(cid:264)ci(cid:241) zaznaczania, czy
chc(cid:241) szuka(cid:232) artysty, czy utworu, ale przy wy(cid:264)wietlaniu rezultatów po-
winny prawdopodobnie by(cid:232) udost(cid:246)pnione filtry pozwalaj(cid:241)ce u(cid:276)ytkowni-
kowi na tym etapie ograniczy(cid:232) zakres wy(cid:264)wietlanych informacji do
odnalezionych artystów lub utworów.
Wyniki wyszukiwania powinny prowadzi(cid:232) do strony z wi(cid:246)ksz(cid:241) ilo(cid:264)ci(cid:241)
informacji na temat znalezionego elementu.
By(cid:228)oby wspaniale, gdyby ta strona zawiera(cid:228)a krótki opis znalezionego
wyniku — biografi(cid:246) artysty lub histori(cid:246) utworu, a tak(cid:276)e linki do bardziej
szczegó(cid:228)owych informacji lub nawet utworów dost(cid:246)pnych online.
Dla zabawy dajmy u(cid:276)ytkownikom mo(cid:276)liwo(cid:264)(cid:232) (cid:264)ledzenia popularno(cid:264)ci
muzyki i artystów, których szukaj(cid:241), dzi(cid:246)ki czemu u(cid:276)ytkownicy b(cid:246)d(cid:241)
mogli oceni(cid:232), jak powszechne s(cid:241) ich zainteresowania.
B(cid:246)dziemy musieli gdzie(cid:264) zapisywa(cid:232) te dane, a w idealnym przypadku
b(cid:246)dziemy potrzebowali jakiego(cid:264) ciekawego sposobu wizualizowania
takich danych.
Oczywi(cid:264)cie do uruchomienia aplikacji b(cid:246)dziemy potrzebowali du(cid:276)ej ilo(cid:264)ci
danych na temat muzyki. Prawdopodobnie najwi(cid:246)ksz(cid:241) korzy(cid:264)ci(cid:241) z tego,
(cid:276)e postanowili(cid:264)my przygotowa(cid:232) tak(cid:241) aplikacj(cid:246) demonstracyjn(cid:241) zamiast
aplikacji do zarz(cid:241)dzania zadaniami, jest fakt, i(cid:276) praktycznie nie jest mo(cid:276)liwe
66
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęsamodzielne zbudowanie kompletnej aplikacji tego typu. Aplikacje do za-
rz(cid:241)dzania zadaniami to wyspy — nie potrzebuj(cid:241) (cid:276)adnych danych, które
nie zosta(cid:228)y wygenerowane przez u(cid:276)ytkownika. Nasza aplikacja, tak jak
wi(cid:246)kszo(cid:264)(cid:232) aplikacji, które b(cid:246)dziesz budowa(cid:232) w realnym (cid:264)wiecie, b(cid:246)dzie
korzysta(cid:232) z komunikacji z us(cid:228)ugami sieciowymi — zewn(cid:246)trznymi serwerami
dostarczaj(cid:241)cymi danych. W tym przypadku przygotowali(cid:264)my aplikacj(cid:246)
komunikuj(cid:241)c(cid:241) si(cid:246) z The Echo Nest (http://the.echonest.com), wspania(cid:228)(cid:241) us(cid:228)ug(cid:241)
music intelligence z bogatym zestawem opcji, olbrzymi(cid:241) i ci(cid:241)gle rosn(cid:241)c(cid:241) ba-
z(cid:241) danych, wspania(cid:228)(cid:241) dokumentacj(cid:241) oraz API dla JavaScript.
Uwaga, spoiler! Oto w jaki sposób zamierzamy to wszystko zrobi(cid:232):
1. Utworzymy szablon, który b(cid:246)dzie mia(cid:228) pole TextField frameworka Ember
po(cid:228)(cid:241)czone ze zmienn(cid:241) o nazwie searchTerms, przekazuj(cid:241)cej dane do
metody action zdefiniowanej w klasie ApplicationController, która prze-
kierowuje do (cid:264)cie(cid:276)ki SearchResultsRoute. Zdefiniowany dla tej (cid:264)cie(cid:276)ki
SearchResultsController odpyta Echo Nest API o dane znajduj(cid:241)ce si(cid:246)
w zmiennej searchTerms.
SearchResultsController odpyta Echo Nest API dwukrotnie, raz zak(cid:228)a-
daj(cid:241)c, (cid:276)e u(cid:276)ytkownik szuka nazwy artysty, i drugi raz szukaj(cid:241)c nazwy
utworu.
2. Nasz szablon search-results przetworzy oddzielnie wyniki wyszuki-
wa(cid:254), tworz(cid:241)c nazwy klas, które pozwol(cid:241) nam zwizualizowa(cid:232) wyniki
wyszukiwania artystów i utworów w inny sposób.
Nasz szablon search-results b(cid:246)dzie zawiera(cid:228) kilka znaczników checkbox
frameworka Ember oraz miejsce do wy(cid:264)wietlenia naszej listy z wyni-
kiem wyszukiwania artystów i utworów z warunkowym wy(cid:264)wietlaniem
zale(cid:276)nym od wybranych warto(cid:264)ci tych kontrolek.
3. Wyniki wyszukiwania Echo Nest zawieraj(cid:241) unikatowy identyfikator ele-
mentów spe(cid:228)niaj(cid:241)cych wyniki wyszukiwania. Nasz szablon search-results
powinien zawiera(cid:232) pola link-to, które b(cid:246)d(cid:241) odno(cid:264)nikami do (cid:264)cie(cid:276)ek
stworzonych specjalnie w celu wy(cid:264)wietlenia szczegó(cid:228)owych danych na
temat artysty (ArtistRoute) oraz utworu (SongRoute). Te (cid:264)cie(cid:276)ki b(cid:246)d(cid:241)
generowa(cid:232) dodatkowe zapytanie do Echo Nest API, pozwalaj(cid:241)ce po-
bra(cid:232) informacje na temat wybranego elementu i przekazuj(cid:241)ce unika-
towy identyfikator zwi(cid:241)zany z odno(cid:264)nikiem, jaki u(cid:276)ytkownik klikn(cid:241)(cid:228)
w wynikach wyszukiwania.
Uzbrojony w model wygenerowany z odpowiedzi Echo Nest widok
ArtistView lub SongView powinien wy(cid:264)wietli(cid:232), pobra(cid:232) obrazki, filmy
oraz tekstowy opis elementu z odpowiedzi Echo Nest, a nast(cid:246)pnie
wype(cid:228)ni(cid:232) nimi szablon artist lub song.
Rock’n’Roll
(cid:95)
67
Kup książkęPoleć książkę 4. Gdy u(cid:276)ytkownik klika wynik wyszukiwania, SearchResultController po-
winien zapisa(cid:232) rekord w lokalnym magazynie wraz ze znacznikiem czasu
i unikatowym identyfikatorem, wy(cid:264)wietlan(cid:241) nazw(cid:241), typem i ocen(cid:241) hottt-
nesss — stosowan(cid:241) wewn(cid:246)trznie przez Echo Nest miar(cid:241) popularno(cid:264)ci
elementu. Pó(cid:274)niej zajmiemy si(cid:246) zapisywaniem tych danych zdalnie.
Odno(cid:264)nik w g(cid:228)ównym panelu nawigacyjnym powinien prowadzi(cid:232)
u(cid:276)ytkownika do ActivityRoute oraz szablonu activity, który powinien
zawiera(cid:232) komponent wykorzystuj(cid:241)cy D3 do wizualizacji aktywno(cid:264)ci
u(cid:276)ytkownika — wszystkich danych pobranych podczas korzystania
przez niego z aplikacji. Poniewa(cid:276) b(cid:246)dziemy wizualizowa(cid:232) parametr o na-
zwie hotttnesss (z ang. „gor(cid:241)co”), to naszym zdaniem mapa termiczna
b(cid:246)dzie w(cid:228)a(cid:264)ciwym rozwi(cid:241)zaniem.
Zaczynamy od HTML
Je(cid:264)li interesowa(cid:228)e(cid:264) si(cid:246) cho(cid:232) troch(cid:246) tematem nowoczesnych metodologii two-
rzenia stron internetowych, musia(cid:228)e(cid:264) s(cid:228)ysze(cid:232) rozmowy o tym, (cid:276)e tradycyjne
sposoby pracy i podej(cid:264)cia trac(cid:241) na znaczeniu. „Kaskadowe” staje si(cid:246) coraz
bardziej zawstydzaj(cid:241)cym s(cid:228)owem. U(cid:276)yteczno(cid:264)(cid:232) wszystkich wykorzysty-
wanych narz(cid:246)dzi i elementów tworzonych podczas prac nad aplikacj(cid:241) jest
podawana w w(cid:241)tpliwo(cid:264)(cid:232). Na przyk(cid:228)ad szkicowanie projektu dynamicznej
aplikacji internetowej w Photoshopie, tworzenie wygl(cid:241)du Twojego serwisu
dla ró(cid:276)nych szeroko(cid:264)ci i wysoko(cid:264)ci, jakie przegl(cid:241)darka mo(cid:276)e wybra(cid:232) (lub
ograniczy(cid:232)), to nieko(cid:254)cz(cid:241)ca si(cid:246) historia. Projektowanie dla idealnych urz(cid:241)dze(cid:254)
— wielkich monitorów stacjonarnych i pot(cid:246)(cid:276)nych procesorów — po prostu
ju(cid:276) nie wystarcza.
Je(cid:264)li to mo(cid:276)liwe, najlepszym rozwi(cid:241)zaniem jest projektowanie w przegl(cid:241)-
darce. Je(cid:264)li jeste(cid:264) projektantem, który potrafi napisa(cid:232) wystarczaj(cid:241)c(cid:241) ilo(cid:264)(cid:232)
kodu HTML i CSS, by zrobi(cid:232) makiet(cid:246), to wspaniale. Je(cid:264)li jeste(cid:264) deweloperem
i musisz wspó(cid:228)pracowa(cid:232) z projektantem, który nie czuje si(cid:246) tak pewnie
w HTML i CSS, w Twoim najlepszym interesie le(cid:276)y jak najwcze(cid:264)niejsze
przygotowanie i jak najcz(cid:246)stsze aktualizowanie takiej makiety. I to jest
jedna ze wspania(cid:228)ych rzeczy przy typowym zastosowaniu Ember: Twoje
szablony s(cid:241) pisane w HTML-u.
W przypadku tej aplikacji zamiast rozpoczyna(cid:232) od szkicowania lub rysowania
projektów, przygotowali(cid:264)my makiet(cid:246), wykorzystuj(cid:241)c HTML i CSS. Mimo
(cid:276)e pracujemy w tej bran(cid:276)y od wielu lat, by(cid:228)o to dla nas nowe do(cid:264)wiadczenie.
Przez wi(cid:246)kszo(cid:264)(cid:232) czasu nasza praca przypomina(cid:228)a prac(cid:246) podwykonawcy
na budowie biegaj(cid:241)cego z planem, m(cid:228)otkiem i mas(cid:241) dodatków. Tym razem
68
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęjednak czuli(cid:264)my si(cid:246) bardziej jak rze(cid:274)biarze — poniewa(cid:276) HTML by(cid:228) tak
plastyczny, (cid:276)e mogli(cid:264)my wszystko dostraja(cid:232), dopóki nie zacz(cid:246)(cid:228)o wygl(cid:241)da(cid:232)
tak, jak chcieli(cid:264)my.
Podstawy Handlebars.js
Mo(cid:276)esz rozpocz(cid:241)(cid:232) swój projekt, po prostu tworz(cid:241)c najprostszy statyczny
HTML. Pó(cid:274)niej wrócisz i wstawisz w odpowiednie miejsca znaczniki, warunki
i zmienne Handlebars. Zacznijmy od stworzenia g(cid:228)ównej zawarto(cid:264)ci naszej
aplikacji: nag(cid:228)ówka, dost(cid:246)pnej globalnie cz(cid:246)(cid:264)ci tre(cid:264)ci strony oraz stopki.
Mo(cid:276)emy po prostu doda(cid:232) kod taki jak poni(cid:276)ej — wykorzystuj(cid:241)cy Twitter
Bootstrap — bezpo(cid:264)rednio do naszego pliku app/templates/application.hbs:
div class= wrapper
div class= navbar navbar-inverse role= navigation
div class= navbar-header
button type= button class= navbar-toggle data-toggle= collapse
data-target= .navbar-ex1-collapse
span class= sr-only Prze(cid:239)(cid:200)cz nawigacj(cid:218) /span
span class= icon-bar /span
span class= icon-bar /span
span class= icon-bar /span
/button
a href= # class= navbar-brand Rock n Roll Call /a
/div
div id= navbar-collapse-1 class= collapse navbar-collapse
ul class= nav navbar-nav search-lockup
li class= search-group
input class= search-input placeholder= Nazwa artysty lub utworu
button class= btn btn-primary i class= glyphicon
glyphicon-play /i /button
/li
/ul
ul class= nav navbar-nav navbar-right
li a href= # Aktywno(cid:258)(cid:202) /a /li
/ul
/div
/div
div class= container-fluid
div class= row-fluid
!-- tutaj zawarto(cid:286)(cid:252) strony --
/div
/div
/div
footer
p
Podstawy Handlebars.js
(cid:95)
69
Kup książkęPoleć książkę i class= glyphicon glyphicon-copyright-mark /i Helion 2015,
em Ember.js dla webdeveloperów /em
/p
p
Autorzy: Jesse Cravens a href= http://twitter.com/jdcravens
@jdcravens /a
i Thomas Q. Brady a href= http://twitter.com/thomasqbrady
@thomasqbrady /a
/p
/footer
A poniewa(cid:276) nie jest to ksi(cid:241)(cid:276)ka na temat CSS, pójdziemy na skróty i doda-
my od razu ca(cid:228)y znajduj(cid:241)cy si(cid:246) w pliku app/styles/style.scss arkusz stylów
dla tej strony, a tak(cid:276)e plik graficzny app/images/stage.jpg. Pliki te mo(cid:276)na
znale(cid:274)(cid:232) w materia(cid:228)ach do(cid:228)(cid:241)czonych do ksi(cid:241)(cid:276)ki, umieszczonych pod adresem
ftp://ftp.helion.pl/przyklady/emberw.zip.
Twitter Bootstrap
Mo(cid:276)e zastanawiasz si(cid:246), w jaki sposób Twitter Bootstrap znalaz(cid:228) si(cid:246)
w Twojej aplikacji. Zosta(cid:228) on dodany przez Yeoman w rozdziale 3.,
po tym, gdy po pytaniu:
Would you like to include Twitter Bootstrap for Sass?
(Y/n)
wybra(cid:228)e(cid:264) Y.
Rysunek 4.1 pokazuje, jak w tym momencie wygl(cid:241)da strona.
Czy powinienem korzysta(cid:235) ze znaczników script ,
czy z plików .hts?
W rozdziale 2. wbudowali(cid:264)my szablony Handlebars w strony HTML
wewn(cid:241)trz znaczników script wygl(cid:241)daj(cid:241)cych tak:
script type= text/x-handlebars data-template-name= application
!-- tutaj kod szablonu --
/script
By(cid:228)o to mo(cid:276)liwe, poniewa(cid:276) korzystali(cid:264)my z pe(cid:228)nej kompilacji Handlebars,
która do(cid:228)(cid:241)cza logik(cid:246) w taki sposób, (cid:276)e w czasie dzia(cid:228)ania wyszukuje znacz-
niki script i konwertuje je na obiekty JavaScript — w rzeczywisto(cid:264)ci
fabryki — w pami(cid:246)ci (w Em.TEMPLATES, je(cid:264)li Ci(cid:246) to ciekawi), gdzie czekaj(cid:241)
gotowe do przetworzenia na kod HTML w zale(cid:276)no(cid:264)ci od potrzeb.
70
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęRysunek 4.1. Szkielet naszej strony po dodaniu CSS
Jak mo(cid:276)na sobie wyobrazi(cid:232), taka konwersja ze znaczników script na fa-
bryki mo(cid:276)e obci(cid:241)(cid:276)a(cid:232) komputer, szczególnie gdy Twoja aplikacja, a wraz
z ni(cid:241) liczba szablonów, b(cid:246)dzie rosn(cid:241)(cid:232). To dlatego Handlebars pozwala
wst(cid:246)pnie kompilowa(cid:232) Twoje szablony i do(cid:228)(cid:241)cza(cid:232) tylko okrojony plik
handlebars.runtime.js, w którym nie ma logiki odpowiedzialnej za kon-
wersj(cid:246), co pozwala zaoszcz(cid:246)dzi(cid:232) czas potrzebny do wyszukiwania sza-
blonów oraz ograniczy(cid:232) ilo(cid:264)(cid:232) danych pobieranych przez Twoj(cid:241) aplikacj(cid:246).
Dzi(cid:246)ki pracy w(cid:228)o(cid:276)onej w przygotowanie Yeoman w rozdziale 2. mo(cid:276)emy
wykorzysta(cid:232) rajdow(cid:241) wersj(cid:246) Handlebars. Yo wygeneruje nam szablony
Handlebars w oddzielnych plikach z rozszerzeniem .hbs podczas gene-
rowania widoków, a Grunt b(cid:246)dzie dla nas pilnowa(cid:228) tych szablonów,
kompiluj(cid:241)c je do postaci klas JavaScript i (cid:228)(cid:241)cz(cid:241)c je z reszt(cid:241) kodu JavaScript za
ka(cid:276)dym razem, gdy b(cid:246)dziemy zapisywa(cid:232) zmiany.
Musisz jedynie powiadomi(cid:232) Grunt, (cid:276)e chcesz, by pilnowa(cid:228) Twoich szablo-
nów Ember, oraz wskaza(cid:232) mu miejsce, w którym si(cid:246) one znajduj(cid:241), w taki
sposób:
grunt.initConfig({
yeoman: yeomanConfig,
watch: {
Podstawy Handlebars.js
(cid:95)
71
Kup książkęPoleć książkę emberTemplates: {
files: = yeoman.app /templates/**/*.hbs ,
tasks: [ emberTemplates , connect:livereload ]
}
}
})
Odpowiadaj(cid:241)c na pytanie, mo(cid:276)na powiedzie(cid:232), (cid:276)e nale(cid:276)y korzysta(cid:232) z pli-
ków .hbs, gdy tylko jest to mo(cid:276)liwe przy zastosowaniach produkcyjnych.
Znaczniki script sprawdzaj(cid:241) si(cid:246) przy tworzeniu szkiców lub bardzo
ma(cid:228)ych zada(cid:254).
Zmienne
Maj(cid:241)c ju(cid:276) stron(cid:246), która wykonuje to, czego potrzebujemy, i wygl(cid:241)da tak,
jak chcemy, mo(cid:276)emy zacz(cid:241)(cid:232) zamienia(cid:232) statyczne elementy na elementy
programowe, wykorzystuj(cid:241)c Handlebars. Zacznijmy od nazwy naszej aplikacji.
Powiedzmy, (cid:276)e chcesz modyfikowa(cid:232) nazw(cid:246) naszej aplikacji tak, by na
przyk(cid:228)ad szwedzkim u(cid:276)ytkownikom wy(cid:264)wietla(cid:232) Rock Upprop. Aby to wy-
kona(cid:232), b(cid:246)dziemy potrzebowali przynajmniej dwóch rzeczy:
1. Musimy u(cid:276)y(cid:232) Handlebars, by wy(cid:264)wietli(cid:232) zmienn(cid:241) w miejscu naszej
statycznej tre(cid:264)ci HTML.
2. Musimy gdzie(cid:264) zdefiniowa(cid:232) t(cid:246) zmienn(cid:241).
W praktyce definiowanie takiej zmiennej mo(cid:276)e okaza(cid:232) si(cid:246) do(cid:264)(cid:232) skomplikowa-
ne. Na razie umie(cid:264)(cid:232)my po prostu zmienn(cid:241) w naszym obiekcie Rocknroll
(cid:180)callYeoman. Przy okazji przyjrzyjmy si(cid:246) kodowi JavaScript utworzonemu
przez Yeoman w naszym pliku app/scripts/app.js:
var RocknrollcallYeoman = window.RocknrollcallYeoman =
(cid:180)Ember.Application.create();
/* Order and include as you please. (Przestawiaj i dodawaj w razie potrzeby.) */
require( scripts/controllers/* );
require( scripts/store );
require( scripts/models/* );
require( scripts/routes/* );
require( scripts/views/* );
require( scripts/router );
Dodajmy tak(cid:241) lini(cid:246) zaraz po wywo(cid:228)aniu Ember.Application.create():
RocknrollcallYeoman.applicationName = Rock n Roll Call ;
72
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęPó(cid:274)niej mo(cid:276)emy doda(cid:232) troch(cid:246) wi(cid:246)cej kodu wstawiaj(cid:241)cego do zmiennej
tekst w obs(cid:228)ugiwanych j(cid:246)zykach. Wprowadzona tutaj zmiana sprawia, (cid:276)e do-
póki b(cid:246)dziemy korzysta(cid:232) z kontrolek Handlebars we wszystkich miejscach,
gdzie wy(cid:264)wietlamy nazw(cid:246) naszej aplikacji, dopóty zmiana nazwy naszej
aplikacji b(cid:246)dzie wymaga(cid:228)a wprowadzenia modyfikacji w jednym miejscu.
Wró(cid:232)my wi(cid:246)c do naszego szablonu. Teraz mo(cid:276)emy po prostu zmodyfiko-
wa(cid:232) lini(cid:246):
a href= # class= navbar-brand Rock n Roll Call /a
do takiej postaci:
a href= # class= navbar-brand {{RocknrollcallYeoman.applicationName}} /a
Jak ju(cid:276) wcze(cid:264)niej widzieli(cid:264)my, nie ogranicza si(cid:246) to do wstawienia zmiennej
podczas (cid:228)adowania strony. Je(cid:264)li zawarto(cid:264)(cid:232) zmiennej RocknrollcallYeoman.appli
(cid:180)cationName zmieni si(cid:246) podczas korzystania z aplikacji — na przyk(cid:228)ad je(cid:264)li
u(cid:276)ytkownik zmieni w opcjach wybrany j(cid:246)zyk — zawarto(cid:264)(cid:232) wy(cid:264)wietlana
w tym polu zostanie zaktualizowana automatycznie bez konieczno(cid:264)ci pi-
sania dodatkowego kodu ponad to, co ju(cid:276) zosta(cid:228)o napisane.
Tworzenie odno(cid:316)ników za pomoc(cid:233) {{link-to}}
Zacznijmy od najprostszego przypadku. Prawdopodobnie zechcemy, by
po klikni(cid:246)ciu logo mo(cid:276)na by(cid:228)o wróci(cid:232) do domy(cid:264)lnego stanu aplikacji, ta-
kiego jaki otrzymujemy po wpisaniu w przegl(cid:241)darce podstawowego adresu.
Nie utworzyli(cid:264)my jeszcze (cid:276)adnych (cid:264)cie(cid:276)ek ani kontrolerów, ale nie ozna-
cza to, (cid:276)e nie zrobi(cid:228) tego Ember. Strona, któr(cid:241) ogl(cid:241)damy w przegl(cid:241)darce,
to... zgadniesz? Jest to domy(cid:264)lna (cid:264)cie(cid:276)ka IndexRoute znajduj(cid:241)ca si(cid:246) w do-
my(cid:264)lnej ApplicationRoute. Tutaj nasz u(cid:276)ytkownik powinien wpisa(cid:232) tekst do
wyszukania i wcisn(cid:241)(cid:232) Enter lub klikn(cid:241)(cid:232) odpowiedni przycisk, co powinno
doprowadzi(cid:232) go do (cid:264)cie(cid:276)ki z wynikami wyszukiwania. Mo(cid:276)e on te(cid:276) klikn(cid:241)(cid:232)
odno(cid:264)nik, by zobaczy(cid:232) wizualizacj(cid:246) swojej aktywno(cid:264)ci w wyszukiwarce, co
powinno skierowa(cid:232) go do ActivityRoute. Dlatego je(cid:264)li zechce on wróci(cid:232) do
strony, na któr(cid:241) w tej chwili patrzymy, powinien wróci(cid:232) do IndexRoute.
Dobrze, to do(cid:264)(cid:232) proste. Zamie(cid:254) znacznik a na znacznik link-to Handlebars
w poni(cid:276)szy sposób.
Statyczny HTML:
a href= # class= navbar-brand {{RocknrollcallYeoman.applicationName}} /a
nale(cid:276)y zmieni(cid:232) na szablon Handlebars:
{{#link-to index class= navbar-
brand }}{{RocknrollcallYeoman.applicationName}}{{/link-to}}
Tworzenie odno(cid:316)ników za pomoc(cid:233) {{link-to}}
(cid:95)
73
Kup książkęPoleć książkęPrawdopodobnie rozumiesz t(cid:246) sk(cid:228)adni(cid:246). Nawiasy {{ i }} po prostu zast(cid:246)-
puj(cid:241) i z HTML-a. Tak samo jak w HTML-u link-to sk(cid:228)ada si(cid:246) ze znacznika
otwieraj(cid:241)cego {{#link-to ...}} oraz znacznika zamykaj(cid:241)cego {{/link-to}}.
Wewn(cid:241)trz znacznika otwieraj(cid:241)cego tak jak w HTML-u mo(cid:276)na zadeklaro-
wa(cid:232) atrybuty znacznika a, który zostanie umieszczony na stronie, i w tym
przyk(cid:228)adzie zadeklarowali(cid:264)my nazw(cid:246) klasy navbar-brand. Cz(cid:246)(cid:264)(cid:232), która mo-
(cid:276)e Ci(cid:246) zastanawia(cid:232), to ci(cid:241)g znaków przed t(cid:241) deklaracj(cid:241) nazwy klasy: index.
Podczas gdy w znaczniku HTML deklarujesz cel atrybutem href, w znacz-
niku Handlebars link-to przekazujesz nazw(cid:246) (cid:264)cie(cid:276)ki jako pierwszy para-
metr. Konwencja nazewnictwa jest prosta, gdy tylko si(cid:246) j(cid:241) zrozumie. Bie-
rzesz nazw(cid:246) (cid:264)cie(cid:276)ki (w tym przypadku IndexRoute), zamieniasz pierwsz(cid:241)
liter(cid:246) na ma(cid:228)(cid:241), usuwasz ci(cid:241)g Route, wstawiasz minus przed ka(cid:276)d(cid:241) wielk(cid:241)
liter(cid:241) oprócz pierwszej, rozdzielasz s(cid:228)owa, je(cid:264)li jest wi(cid:246)cej ni(cid:276) jedno, i zamie-
niasz wszystkie litery na ma(cid:228)e. Opis mo(cid:276)e wydawa(cid:232) si(cid:246) skomplikowany,
ale ma to sens. Zobaczmy na przyk(cid:228)adach:
(cid:120) (cid:263)cie(cid:276)ka IndexRoute powinna by(cid:232) przekazana do link-to jako index.
(cid:120) (cid:263)cie(cid:276)ka SearchResultsRoute powinna by(cid:232) przekazana do link-to jako
search-results.
Wszystkie informacje na temat konwencji nazewnictwa mo(cid:276)na znale(cid:274)(cid:232) w roz-
dziale „Naming Conventions” przewodnika „Ember Guides” pod adresem
http://emberjs.com/guides/concepts/naming-conventions/.
Wprowadzanie danych z {{input}}
Jak mo(cid:276)esz sobie wyobrazi(cid:232), zawarto(cid:264)(cid:232) pola input z tekstem do wyszukiwania
b(cid:246)dzie do(cid:264)(cid:232) wa(cid:276)na. W przypadku samego pola input mo(cid:276)liwe jest uzyskanie
dost(cid:246)pu do jego zawarto(cid:264)ci, a nawet przechwycenie jego przes(cid:228)ania z pozio-
mu samego j(cid:246)zyka JavaScript, ale du(cid:276)o (cid:228)atwiej jest pozwoli(cid:232) zaj(cid:241)(cid:232) si(cid:246) tym
Handlebars i Ember. Zast(cid:241)pmy nasz znacznik input znacznikiem Handlebars:
Statyczny HTML:
input class= search-input placeholder= Nazwa artysty lub utworu
nale(cid:276)y zamieni(cid:232) na szablon Handlebars:
{{input type= text class= search-input placeholder= Nazwa artysty lub utworu }}
W tym miejscu pole input nie b(cid:246)dzie jeszcze zbyt wiele robi(cid:232). (cid:227)(cid:241)czeniem
jego warto(cid:264)ci oraz zdarzeniem submit zajmiemy si(cid:246) w nast(cid:246)pnym rozdziale.
74
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęZwró(cid:232)my teraz uwag(cid:246) na wyniki wyszukiwania. Zaczynamy od makiety
wykonanej w statycznym HTML-u:
div class= container-fluid
div class= row-fluid
div class= search-results-wrapper clearfix
div class= search-facets col-md-2
h3 Pokazuj: /h3
ul class= facets
li
label Artystów /label
input type= checkbox checked= checked
/li
li
label Utwory /label
input type= checkbox checked= checked
/li
/ul
/div
div class= results col-md-10
h3 Arty(cid:258)ci /h3
ul class= search-results artists
li a href= # Tom Waits /a /li
li a href= # Tom Waits Keith Richards /a /li
li a href= # Tom Waits Keith Richards /a /li
li a href= # Tom Waits [Vocalist] Orchestra [Orchestra]
Michael Riesman [Conductor] Bryars, Gavin
[Composer] /a /li
li a href= # Tom Waits [Vocals] Gavin Bryars Ensemble
[Ensemble] /a /li
li a href= # Tom Waits [Vocalist]; Orchestra [Orchestra];
Michael Riesman [Conductor] /a /li
li a href= # Tom Waits [Vocals] Gavin Bryars Ensemble
[Ensemble] Bryars, Gavin [Composer] /a /li
li a href= # Tom Waits [Vocalist], Orchestra [Orchestra]
Michael Riesman [Conductor] /a /li
/ul
h3 Utwory /h3
ul class= search-results songs
li a href= # Tom Waits - Panic Strikes a Chord /a /li
li a href= # Tom Waits - Doug Kuony /a /li
li a href= # Tom Waits - The Moonband /a /li
li a href= # Tom Waits - The Moonband /a /li
li a href= # Tom Waits - Spaghetti Western /a /li
li a href= # Tom Waits - The Passionate Objective
(cid:180)Jokerfan /a /li
li a href= # Tom Waits - Mike Macharyas /a /li
li a href= # Tom Waits - Junkyard Poets /a /li
li a href= # Tom Waits - The Fall of Troy /a /li
li a href= # Tom Waits - Anouk /a /li
/ul
/div
Wprowadzanie danych z {{input}}
(cid:95)
75
Kup książkęPoleć książkę /div
/div
/div
Na razie dodamy te wyniki do pliku app/templates/index.hbs. Nast(cid:246)pnie
w pliku app/templates/application.hbs zmienimy lini(cid:246) z komentarzem:
!-- tutaj zawarto(cid:286)(cid:252) strony --
na znacznik handlebars:
{{outlet}}
aby wskaza(cid:232) frameworkowi Ember, w którym miejscu nale(cid:276)y wy(cid:264)wietli(cid:232)
szablon zwi(cid:241)zany z bie(cid:276)(cid:241)c(cid:241) (cid:264)cie(cid:276)k(cid:241) (index).
Rysunek 4.2 pokazuje wygl(cid:241)d strony w tej chwili.
Rysunek 4.2. Wy(cid:264)wietlony szablon z wynikami wyszukiwania
Ale czym s(cid:241) {{outlet}}, IndexRoute i index.hbs?
Nie wyja(cid:264)nili(cid:264)my jeszcze, jak mo(cid:276)na przechodzi(cid:232) mi(cid:246)dzy ró(cid:276)nymi
szablonami. Na razie jednak wystarczy wiedza, (cid:276)e wy(cid:264)wietlamy
tre(cid:264)ci zwi(cid:241)zane z IndexRoute oraz szablonem index.hbs w miejsce
{{outlet}} w szablonie application.hbs. W kolejnym rozdziale omó-
wimy tworzenie nowych szablonów, (cid:264)cie(cid:276)ek i (cid:228)(cid:241)czenie wszystkiego
ze sob(cid:241).
76
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęListy z {{each}}
Mo(cid:276)liwe, (cid:276)e listy nienumerowane b(cid:246)d(cid:241) pierwszym elementem, w którym
korzy(cid:264)(cid:232) z u(cid:276)ywania szablonów b(cid:246)dzie dla Ciebie oczywista. Handlebars
obs(cid:228)uguje je w bardzo przyjazny sposób. Najpierw zredukujmy ka(cid:276)d(cid:241)
z takich list do jednego elementu, a nast(cid:246)pnie zobaczymy, jak zwielokrotni(cid:232)
ten szablon dla ka(cid:276)dego elementu otrzymanego w wynikach wyszukiwania.
Lista artystów w wersji HTML wygl(cid:241)da tak:
ul class= search-results artists
li a href= # Tom Waits /a /li
/ul
Istotne jest to, (cid:276)e b(cid:246)dziemy chcieli wykorzysta(cid:232) jeden znacznik ul, taki jak
tutaj, ale zechcemy umie(cid:264)ci(cid:232) wi(cid:246)ksz(cid:241) ilo(cid:264)(cid:232) znaczników li wewn(cid:241)trz niego.
Handlebars obs(cid:228)uguje znacznik each, który przechodz(cid:241)c przez kolejne
elementy tablicy, tworzy co(cid:264) w rodzaju wewn(cid:246)trznego szablonu dla ka(cid:276)-
dego elementu tablicy. Zacznijmy od stworzenia prostej tablicy, któr(cid:241) b(cid:246)-
dziemy mogli wy(cid:264)wietli(cid:232). Do pliku app.js dodaj poni(cid:276)sze linie po deklaracji
applicationName:
RocknrollcallYeoman.dummySearchResultsArtists = [
{
id: 1,
name: Tom Waits ,
nickname: Tommy ,
type: artist ,
enid: ARERLPG1187FB3BB39
},
{
id: 2,
name: Thomas Alan Waits ,
type: artist ,
enid: ARERLPG1187FB3BB39
},
{
id: 3,
name: Tom Waits Keith Richards ,
type: artist ,
enid: ARMPVNN13CA39CF8FC
}
];
Teraz mo(cid:276)emy wykorzysta(cid:232) t(cid:246) tablic(cid:246) w naszym szablonie. Zast(cid:241)p znacz-
nik li z kodu HTML znacznikiem each Handlebars w taki sposób:
ul class= search-results artists
{{#each RocknrollcallYeoman.dummySearchResultsArtists}}
li a href= # {{name}} /a /li
{{/each}}
/ul
Listy z {{each}}
(cid:95)
77
Kup książkęPoleć książkęMagia, prawda? Nie jest nawet najwa(cid:276)niejsze, (cid:276)e mechanizm ten przetwa-
rza nasz(cid:241) zmienn(cid:241) globaln(cid:241). Cz(cid:246)sto w Ember i Handlebars naprawd(cid:246) ma-
giczne rzeczy dziej(cid:241) si(cid:246), gdy warto(cid:264)(cid:232) zapisana w przekazanej zmiennej —
w naszym przypadku globalnej zmiennej dummySearchResultsArtists — ulega
zmianie, a Twoja lista automatycznie si(cid:246) aktualizuje.
Zauwa(cid:276), (cid:276)e kontekst — lub zakres zmiennej — zmienia si(cid:246) wewn(cid:241)trz
znacznika each. Do w(cid:246)z(cid:228)a text w naszym znaczniku a odwo(cid:228)ujemy si(cid:246), po
prostu pisz(cid:241)c {{name}}, a nie App.dummySearchResultsArtists[index].name czy
co(cid:264) w tym rodzaju. Wewn(cid:241)trz p(cid:246)tli each kontekst wskazuje na bie(cid:276)(cid:241)cy obiekt
z tablicy i mo(cid:276)esz uzyska(cid:232) dost(cid:246)p do jego w(cid:228)a(cid:264)ciwo(cid:264)ci, odwo(cid:228)uj(cid:241)c si(cid:246) do nich
za pomoc(cid:241) nazwy.
Co by by(cid:228)o, gdyby(cid:264)my w ka(cid:276)dym z naszych obiektów dummySearchResults
(cid:180)Artists mieli w(cid:228)a(cid:264)ciwo(cid:264)(cid:232) nicknames, która by(cid:228)aby tablic(cid:241) pseudonimów
u(cid:276)ywanych przez artyst(cid:246)? Przypu(cid:264)(cid:232)my, (cid:276)e chcieliby(cid:264)my wy(cid:264)wietli(cid:232) wszystkie
te pseudonimy w postaci oddzielnych wyników wyszukiwania w taki
sposób, (cid:276)e „TAFKAP” — „The Artist Formely Known as Prince” — by(cid:228)by
oddzielnym elementem w wynikach wyszukiwania. Aby unikn(cid:241)(cid:232) nieporo-
zumie(cid:254), dopiszemy alias [prawdziwe nazwisko lub oryginalna nazwa]. W ko(cid:254)cu
kto(cid:264) mo(cid:276)e szuka(cid:232) artysty, wpisuj(cid:241)c jego pseudonim i nie wiedz(cid:241)c nawet
o tym, (cid:276)e jest to pseudonim.
Mog(cid:228)e(cid:264) pomy(cid:264)le(cid:232), (cid:276)e takie prze(cid:228)(cid:241)czanie kontekstu mo(cid:276)e w takim wypadku
nie by(cid:232) zbyt wygodnym rozwi(cid:241)zaniem. Zobaczmy dlaczego. Oto pierwszy
element naszego teoretycznego szablonu (bardzo by(cid:264)my tego chcieli, ale The
Echo Nest nie podaje pseudonimów):
ul class= search-results artists
{{#each RocknrollcallYeoman.dummySearchResultsArtists}}
{{#each ...
No dobra! Jak mamy odwo(cid:228)ywa(cid:232) si(cid:246) do naszego lokalnego obiektu? Cho(cid:232)
nie b(cid:246)dziesz tego zbyt cz(cid:246)sto u(cid:276)ywa(cid:228), mo(cid:276)e nawet nie u(cid:276)yjesz nigdy, oka-
zuje si(cid:246), (cid:276)e mo(cid:276)esz to zrobi(cid:232) w ten sposób:
ul class= search-results artists
{{#each RocknrollcallYeoman.dummySearchResultsArtists}}
li a href= # {{this.name}}, alias {{this.nickname}} /a /li
{{/each}}
/ul
Ale u(cid:276)ycie this tutaj nie wygl(cid:241)da zbyt dobrze, dlatego mamy szcz(cid:246)(cid:264)cie, (cid:276)e
Handlebars umo(cid:276)liwia skorzystanie z innej sk(cid:228)adni znacznika each, co po-
zwoli nam nazwa(cid:232) zmienn(cid:241) w taki sposób:
ul class= search-results artists
{{#each artist in RocknrollcallYeoman.dummySearchResultsArtists}}
78
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkę li a href= # {{artist.nickname}}, alias {{artist.name}} /a /li
{{/each}}
/ul
A je(cid:264)li zechcesz jeszcze bardziej skróci(cid:232) i upro(cid:264)ci(cid:232), nawet nie musisz u(cid:276)y-
wa(cid:232) this ani nazwy zmiennej. Handlebars domy(cid:264)lnie zak(cid:228)ada, (cid:276)e bie(cid:276)(cid:241)cy
obiekt modelu z przetwarzanej tablicy jest bie(cid:276)(cid:241)cym kontekstem:
ul class= search-results artists
{{#each RocknrollcallYeoman.dummySearchResultsArtists}}
li a href= # {{nickname}}, alias {{name}} /a /li
{{/each}}
/ul
Teraz jednak trafili(cid:264)my na inny problem. Nasi arty(cid:264)ci z pseudonimami (cid:228)adnie
si(cid:246) wy(cid:264)wietlaj(cid:241), ale arty(cid:264)ci bez pseudonimów nie pojawiaj(cid:241) si(cid:246) wcale. Gdy
zajrzymy do kodu, okazuje si(cid:246), (cid:276)e ma to sens. Je(cid:264)li nie masz tablicy o nazwie
nicknames, omijasz równie(cid:276) cz(cid:246)(cid:264)(cid:232) kodu. Potrzebujemy czego(cid:264) w rodzaju
klauzuli if. Prawdopodobnie nie zaskoczy Ci(cid:246) to, (cid:276)e Handlebars obs(cid:228)uguje
tak(cid:241) klauzul(cid:246).
Warunki ze znacznikami {{if}} oraz {{else}}
Spróbujmy najpierw sprawdza(cid:232), czy wybrany artysta ma jakie(cid:264) pseudo-
nimy, i na tej podstawie zadecydujmy, czy wy(cid:264)wietli(cid:232) je w p(cid:246)tli, czy sko-
rzysta(cid:232) z prostszego szablonu. Mo(cid:276)e to wygl(cid:241)da(cid:232) tak:
ul class= search-results artists
{{#each RocknrollcallYeoman.dummySearchResultsArtists}}
{{#if nickname}}
li a href= # {{nickname}} alias {{name}} /a /li
{{else}}
li a href= # {{name}} /a /li
{{/if}}
{{/each}}
/ul
Zamie(cid:254) znacznik ul w pliku index.hbs na powy(cid:276)szy kod. Rysunek 4.3 poka-
zuje, jak wygl(cid:241)da strona po takiej modyfikacji.
Mo(cid:276)esz zastanawia(cid:232) si(cid:246), w jakiej sytuacji zawarto(cid:264)(cid:232) atrybutu nicknames jest
uznawana za fa(cid:228)sz. Wszyscy oczekujemy takiego wyniku, gdy do tego atry-
butu przypisana jest warto(cid:264)(cid:232) podobnego typu: fa(cid:228)sz, null, niezdefiniowana.
Co jednak w sytuacji, gdy mamy pust(cid:241) tablic(cid:246): []? Spokojnie, Handlebars
uzna ka(cid:276)d(cid:241) z tych warto(cid:264)ci za fa(cid:228)sz.
Warunki ze znacznikami {{if}} oraz {{else}}
(cid:95)
79
Kup książkęPoleć książkęRysunek 4.3. Nasz szablon wy(cid:264)wietlania wyników z przyk(cid:228)adowymi danymi i kodem
zawieraj(cid:241)cym instrukcje warunkowe
Mo(cid:276)esz ju(cid:276) usun(cid:241)(cid:232) kod zwi(cid:241)zany z obs(cid:228)ug(cid:241) pseudonimów, poniewa(cid:276) by(cid:228)
on do(cid:228)(cid:241)czony jedynie dla demonstracji. W naszej aplikacji nie b(cid:246)dziemy go
u(cid:276)ywa(cid:232), poniewa(cid:276) korzystamy z API istniej(cid:241)cej us(cid:228)ugi Echo Nest.
Obs(cid:293)uga dzia(cid:293)a(cid:295) u(cid:348)ytkownika
za pomoc(cid:233) {{action}}
Znacznik {{action}} s(cid:228)u(cid:276)y do obs(cid:228)ugi zdarze(cid:254) generowanych przez u(cid:276)yt-
kownika korzystaj(cid:241)cego z aplikacji. Akcja zostanie przekazana do kontro-
lera powi(cid:241)zanego z bie(cid:276)(cid:241)c(cid:241) (cid:264)cie(cid:276)k(cid:241). Gdy ju(cid:276) sko(cid:254)czymy omawia(cid:232) (cid:264)cie(cid:276)ki,
nabierze to wi(cid:246)cej sensu, ale z wprowadzenia w rozdziale 2. powiniene(cid:264)
zna(cid:232) przynajmniej podstawy.
Najcz(cid:246)stszym przypadkiem jest wykorzystanie akcji do przejmowania zda-
rze(cid:254) dotycz(cid:241)cych klikni(cid:246)cia odno(cid:264)nika zwi(cid:241)zanego ze znacznikiem a lub
przycisku:
button {{action robCos }} KLIKNIJ MNIE! /button
80
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęAby obs(cid:228)u(cid:276)y(cid:232) tak(cid:241) akcj(cid:246), potrzebujemy odpowiedniego miejsca. Utwórzmy
wi(cid:246)c IndexController w pliku app/scripts/controllers/index_controller.js:
RocknrollcallYeoman.IndexController = Ember.Controller.extend({});
Tworz(cid:241)c kontroler, w rzeczywisto(cid:264)ci przes(cid:228)aniamy istniej(cid:241)cy IndexController,
który Ember wygenerowa(cid:228) dla nas automatycznie. Wi(cid:246)cej informacji na
temat automatycznego generowania znajduje si(cid:246) w nast(cid:246)pnym rozdziale.
Mo(cid:276)emy teraz obs(cid:228)u(cid:276)y(cid:232) akcj(cid:246) w bie(cid:276)(cid:241)cym kontrolerze, którym jest w(cid:228)a(cid:264)nie
utworzony IndexController, poniewa(cid:276) korzystamy z adresu startowego
(http://localhost:9000/). Je(cid:264)li nie wszystko rozumiesz (cid:127) cierpliwo(cid:264)ci; wi(cid:246)cej
na temat routingu dowiesz si(cid:246) w rozdziale 5.
RocknrollcallYeoman.IndexController = Ember.Controller.extend({
actions: {
viewedArtist: function(artist) {
console.log( zaczekaj, przegl(cid:200)dam: + artist.name)
}
}
});
Mo(cid:276)emy teraz korzysta(cid:232) ze znacznika a i specjalnie przygotowanych akcji,
by przej(cid:241)(cid:232) obs(cid:228)ug(cid:246) klikni(cid:246)(cid:232) naszych u(cid:276)ytkowników w pliku index.hbs w taki
sposób:
li a {{action viewedArtist this }} href= # {{name}} /a /li
Wi(cid:246)cej informacji na temat tego, jak obs(cid:228)ugujemy akcje, pojawi si(cid:246) pó(cid:274)niej.
W rozdziale 7. napiszemy bardziej szczegó(cid:228)owo, w jaki sposób trwale zapisy-
wa(cid:232) dane z takich aktywno(cid:264)ci lokalnie i zdalnie.
Powi(cid:233)zane atrybuty
Korzystaj(cid:241)c z naszej dobrej passy, id(cid:274)my dalej. Za(cid:228)ó(cid:276)my, (cid:276)e u(cid:276)ytkownik
klikn(cid:241)(cid:228) nazw(cid:246) artysty w wynikach wyszukiwania i przeszed(cid:228) do strony
opisuj(cid:241)cej wskazany element. W nast(cid:246)pnym rozdziale dowiesz si(cid:246), jak
utworzy(cid:232) now(cid:241) (cid:264)cie(cid:276)k(cid:246) opisuj(cid:241)c(cid:241) stan aplikacji i przej(cid:264)(cid:232) do tej (cid:264)cie(cid:276)ki. Tym-
czasem popatrzmy na ostateczny szablon i przeanalizujmy, co tutaj wi-
dzimy. Do pliku app/templates/artist.hbs dodaj taki kod:
div class= entity-artist page-container
div class= artist-bio-lockup clearfix
{{#if model.image}}
{{#if model.license}}
{{#if model.license.url}}
a {{bind-attr href= model.license.url }}
img {{bind-attr src= model.image.url }} class= pull-right
/a
Powi(cid:233)zane atrybuty
(cid:95)
81
Kup książkęPoleć książkę {{else}}
img {{bind-attr src= model.image.url }} class= pull-right
{{/if}}
{{else}}
img {{bind-attr src= model.image.url }} class= pull-right
{{/if}}
{{/if}}
h3 class= fancy {{model.name}} /h3
h4
{{hotttnesss-badge model.hotttnesss}}
/h4
p class= bio pull-left Biografia(from {{model.biography.site}}):
{{model.biography.text}} /p
a {{bind-attr href= model.biography.url }} class= pull-left Wi(cid:218)cej
(cid:180)informacji /a
/div
{{#if model.videos.length}}
div class= videos
h5 Filmy /h5
{{#each video in videos}}
a {{bind-attr href= video.url }} img {{bind-attr
src= video.image_url }} class= video-thumbnail /a
{{/each}}
/div
{{/if}}
/div
Popatrz na powy(cid:276)szy fragment kodu kilka razy. I co? Wida(cid:232) tutaj tylko je-
den nowy element Ember. S(cid:241) nim atrybuty bind-attr w szablonie, które s(cid:241)
otoczone nawiasami klamrowymi i znajduj(cid:241) si(cid:246) wewn(cid:241)trz znaczników
HTML w miejscu, w którym zazwyczaj znajduj(cid:241) si(cid:246) atrybuty. Jest tak, ponie-
wa(cid:276) w ko(cid:254)cu zostan(cid:241) one zamienione na atrybuty. Dyrektywa bind-attr
pozwala dynamicznie przypisywa(cid:232) dowolny atrybut HTML z dost(cid:246)pnych
zmiennych bie(cid:276)(cid:241)cego kontekstu w czasie dzia(cid:228)ania aplikacji — najcz(cid:246)(cid:264)ciej
w modelu, ale mo(cid:276)e by(cid:232) to te(cid:276) co(cid:264) wygenerowanego przez kontroler, wi-
dok lub (cid:264)cie(cid:276)k(cid:246). Sk(cid:228)adnia jest do(cid:264)(cid:232) prosta. Nie jest to znacznik, dlatego nie
ma tutaj cz(cid:246)(cid:264)ci otwieraj(cid:241)cej i zamykaj(cid:241)cej i dlatego te(cid:276) nie ma konieczno(cid:264)ci
u(cid:276)ycia znaku # ani zamykaj(cid:241)cego znaku uko(cid:264)nika. Po prostu piszemy:
[dowolny znacznik] {{bind-attr }}
Nast(cid:246)pnie wskazujemy, jaki atrybut chcemy wstawi(cid:232) — w tym przypadku
utwórzmy link roboczy:
a {{bind-attr href=video.url}} Zobacz na Vimeo /a
Przygl(cid:241)daj(cid:241)c si(cid:246) naszemu szablonowi, zobaczysz wiele przyk(cid:228)adów uzu-
pe(cid:228)niania atrybutów href, atrybutów src obrazków i jeden przyk(cid:228)ad atry-
butu data-. Mo(cid:276)esz wykorzystywa(cid:232) dowolne atrybuty w miar(cid:246) potrzeb,
82
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęw tym atrybut class. Cho(cid:232) atrybut class jest troch(cid:246) bardziej k(cid:228)opotliwy,
poniewa(cid:276) cz(cid:246)sto masz wi(cid:246)cej ni(cid:276) jeden i ka(cid:276)dy z nich b(cid:246)dzie musia(cid:228) by(cid:232)
po(cid:228)(cid:241)czony z innymi danymi. Handlebars dostarcza wielu sposobów zarz(cid:241)-
dzania mnóstwem kombinacji dynamicznych i statycznych po(cid:228)(cid:241)cze(cid:254) z na-
zwami klas, wszystkie s(cid:241) opisane w dokumentacji Ember.js, w rozdziale
„Binding Element Class Names” pod adresem http://emberjs.com/guides/
templates/binding-element-class-names/.
Zobaczmy teraz, jak mo(cid:276)emy utworzy(cid:232) w(cid:228)asny znacznik, by poprawi(cid:232) kod,
którego u(cid:276)yli(cid:264)my wcze(cid:264)niej do wy(cid:264)wietlania oznaczenia hotttnesss.
Tworzenie w(cid:293)asnych znaczników
Jak dot(cid:241)d zajmowali(cid:264)my si(cid:246) znacznikami istniej(cid:241)cymi wcze(cid:264)niej w Ember.js,
takimi jak np. znacznik Handlebars input. Znacznik input jest w rzeczywisto(cid:264)ci
do(cid:228)(cid:241)czony do biblioteki Ember.js jako rozszerzenie Handlebars. W chwili pi-
sania tego tekstu znajduje si(cid:246) on w linii nr 31 514 w pliku Ember.js
1.4.1+pre.af87bd20:
Ember.Handlebars.registerHelper( input , function(options) {
Ember.assert( You can only pass attributes to the `input` helper, not
(cid:180)arguments , arguments.length 2);
var hash = options.hash,
types = options.hashTypes,
inputType = hash.type,
onEvent = hash.on;
delete hash.type;
delete hash.on;
if (inputType === checkbox ) {
return Ember.Handlebars.helpers.view.call(this, Ember.Checkbox, options);
} else {
if (inputType) { hash.type = inputType; }
hash.onEvent = onEvent || enter ;
return Ember.Handlebars.helpers.view.call(this, Ember.TextField, options);
}
});
Ciekawe jest to, (cid:276)e mo(cid:276)emy tworzy(cid:232) swoje w(cid:228)asne znaczniki Handlebars,
korzystaj(cid:241)c z tego samego wzorca, jaki zosta(cid:228) zastosowany do wykorzy-
stania Handlebars jako rozszerzenie. Aby to pokaza(cid:232), utworzymy znacz-
nik hotttnesss, który b(cid:246)dzie wy(cid:264)wietla(cid:228) p(cid:228)omienie oraz liczb(cid:246) odpowiada-
j(cid:241)c(cid:241) parametrowi hotttnesss z naszego modelu.
Tworzenie w(cid:293)asnych znaczników
(cid:95)
83
Kup książkęPoleć książkęGdyby(cid:264)my mieli robi(cid:232) to bez tworzenia znacznika, musieliby(cid:264)my doda(cid:232)
wiele elementów z ikonami do app/templates/index.hbs w taki sposób:
h4
Hotness:
{{#if model.hotttnesss}}
i class= hotttnesss
i class= glyphicon glyphicon-fire hotttnesss0 /i
i class= glyphicon glyphicon-fire hotttnesss1 /i
i class= glyphicon glyphicon-fire hotttnesss2 /i
i class= glyphicon glyphicon-fire hotttnesss3 /i
i class= glyphicon glyphicon-fire hotttnesss4 /i
i class= glyphicon glyphicon-fire hotttnesss5 /i
i class= glyphicon glyphicon-fire hotttnesss6 /i
i class= glyphicon glyphicon-fire hotttnesss7 /i
i class= glyphicon glyphicon-fire hotttnesss8 /i
i class= glyphicon glyphicon-fire hotttnesss9 /i
/i
span class= hotttnesss-badge {{bindAttr data-hotttnesss =
model.hotttnesss }} /span
{{/if}}
/h4
Musieliby(cid:264)my te(cid:276) utworzy(cid:232) styl dla ka(cid:276)dej z tych ikon. Poni(cid:276)ej pokazuje-
my jeden taki styl dla hotttnesss0:
h4 .hotttnesss .hotttnesss0 {
font-size: 190 ;
top: -45 ;
left: -45 ;
position: absolute;
color: #FF0000;
direction: rtl;
unicode-bidi: bidi-override;
}
Tak wi(cid:246)c zamiast do(cid:228)(cid:241)cza(cid:232) wszystkie 10 elementów, mo(cid:276)emy napisa(cid:232)
znacznik, który do(cid:228)(cid:241)czy odpowiedni kod HTML, wykorzystuj(cid:241)c informa-
cj(cid:246) z modelu. Zrobimy to, zamieniaj(cid:241)c parametr hotttnesss zapisany jako
warto(cid:264)(cid:232) z zakresu od 0 do 1 na warto(cid:264)(cid:232) z zakresu od 1 do 10, by nast(cid:246)pnie
utworzy(cid:232) w p(cid:246)tli odpowiedni kod HTML i wy(cid:264)wietli(cid:232) go. Dodaj poni(cid:276)szy
kod na ko(cid:254)cu pliku app.js:
Ember.Handlebars.helper( hotttnesss-badge , function(value, options) {
var h = parseFloat(value);
var hotttnesss_num = Math.round(h * 100);
var hotttnesss_css = Math.ceil(h * 10) - 1;
var html = h4 Hotness: ;
if (hotttnesss_num 0) {
html += i class= hotttnesss ;
for (var i=0; i hotttnesss_css; i++) {
html += i class= glyphicon glyphicon-fire hotttnesss +i+ /i ;
}
84
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkę html += /i ;
html += span class= hotttnesss-badge +hotttnesss_css+ /span /h4 ;
} else {
html += 0 /h4 ;
}
return new Handlebars.SafeString(html);
});
W ko(cid:254)cu musimy te(cid:276) doda(cid:232) w(cid:228)a(cid:264)ciwo(cid:264)(cid:232) hotttnesss do naszych przyk(cid:228)a-
dowych danych w app/scripts/app.js:
RocknrollcallYeoman.dummySearchResultsArtists = [
{
id: 1,
name: Tom Waits ,
type: artist ,
enid: ARERLPG1187FB3BB39 ,
hotttnesss: 1
},
{
id: 2,
name: Thomas Alan Waits ,
type: artist ,
enid: ARERLPG1187FB3BB39 ,
hotttnesss: .89
},
{
id: 3,
name: Tom Waits Keith Richards ,
type: artist ,
enid: ARMPVNN13CA39CF8FC ,
hotttnesss: .79
}
];
Mo(cid:276)emy teraz doda(cid:232) znacznik do szablonu w pliku index.hbs i przekaza(cid:232)
dane z modelu jako pierwszy parametr w taki sposób:
{{hotttnesss-badge hotttnesss}}
Na rysunku 4.4 mo(cid:276)na zobaczy(cid:232), jak wygl(cid:241)da w tej chwili strona.
I w ko(cid:254)cu si(cid:246) uda(cid:228)o. Nie tylko ograniczyli(cid:264)my si(cid:246) do potrzebnego kodu,
ale upro(cid:264)cili(cid:264)my te(cid:276) nasz szablon do jednej deklaracji znacznika.
Takie dane bardziej pasuj(cid:241) do strony wy(cid:264)wietlaj(cid:241)cej szczegó(cid:228)owe informa-
cje, do której mo(cid:276)emy przej(cid:264)(cid:232), gdy chcemy dowiedzie(cid:232) si(cid:246) wi(cid:246)cej na temat
wybranego elementu z wyników wyszukiwania. W nast(cid:246)pnym rozdziale
przygotujemy te widoki i wtedy przeniesiemy znacznik Hotness na strony
opisuj(cid:241)ce utwór oraz artyst(cid:246).
Tworzenie w(cid:293)asnych znaczników
(cid:95)
85
Kup książkęPoleć książkęRysunek 4.4. Znacznik Hotness
Podsumowanie
Zrób sobie chwil(cid:246) przerwy i pomy(cid:264)l o tym, co do tej pory zrobili(cid:264)my. Na-
pisali(cid:264)my zdecydowan(cid:241) wi(cid:246)kszo(cid:264)(cid:232) kodu HTML dla naszej witryny, przy
czym du(cid:276)(cid:241) cz(cid:246)(cid:264)(cid:232) w taki sposób, (cid:276)e kod jest tworzony dynamicznie, wsta-
wiane s(cid:241) dane modelu, warunkowo wy(cid:264)wietlane mog(cid:241) by(cid:232) cz(cid:246)(cid:264)ci szablonu,
a nawet w p(cid:246)tlach przetwarzane s(cid:241) tablice z modelu.
Zastanów si(cid:246) te(cid:276) nad tym, jakiego rodzaju prac(cid:246) wykonali(cid:264)my. Wi(cid:246)ksz(cid:241)
cz(cid:246)(cid:264)(cid:232) tej pracy móg(cid:228)by wykona(cid:232) dowolny cz(cid:228)onek zespo(cid:228)u bez specjalnych
kwalifikacji. Ka(cid:276)dy, kto potrafi edytowa(cid:232) HTML, móg(cid:228)by wykona(cid:232) wi(cid:246)kszo(cid:264)(cid:232)
pracy, a bardzo mo(cid:276)liwe, (cid:276)e po w(cid:228)o(cid:276)eniu odrobiny wysi(cid:228)ku i nauczeniu
si(cid:246), jak nale(cid:276)y korzysta(cid:232) ze zmiennych, po(cid:228)(cid:241)czonych atrybutów oraz instrukcji
warunkowych, ten sam cz(cid:228)owiek móg(cid:228)by wykona(cid:232) ca(cid:228)(cid:241) opisan(cid:241) w tym
rozdziale prac(cid:246) bez Ciebie. Czy(cid:276) nie jest to pot(cid:246)(cid:276)ne narz(cid:246)dzie?
Wiedz(cid:241)c ju(cid:276) to wszystko, przejd(cid:274)my do rzeczy, którymi b(cid:246)dziesz si(cid:246) zajmo-
wa(cid:228), gdy Twoi praktykanci b(cid:246)d(cid:241) przygotowywa(cid:232) kod HTML. Trzeba utwo-
rzy(cid:232) prawdziwe modele oraz sprawi(cid:232), by zapisane w nich dane w ko(cid:254)cu
pojawia(cid:228)y si(cid:246) w szablonach. W rozdziale 5. przyjrzymy si(cid:246) routerom i pro-
stym modelom, by dowiedzie(cid:232) si(cid:246), jak to zrobi(cid:232).
86
(cid:95)
Rozdzia(cid:293) 4. Prototyp aplikacji Rock’n’Roll Call: szablony
Kup książkęPoleć książkęSkorowidz
B
Backbone.js, 87
baza danych, 162
migracja, 160
testowa, 157
zdalna, 144
biblioteka
D3.js, 169
Ember.js, 51
ORM, 127
po stronie klienta, 127
RSVP.js, Patrz: RSVP
b(cid:228)(cid:241)d, 179
obs(cid:228)uga, 126
wyszukiwanie automatyczne, 54
panel konfiguracyjny, 87
Bower, 45, 53, 136
C
Chrome, 57
CoffeeScript, 54
Compass, 54
instalowanie, 46
generowana
CORS, 185, 186
CSS, 68
computed property, Patrz: w(cid:228)a(cid:264)ciwo(cid:264)(cid:232)
D
dane
baza, Patrz: baza danych
(cid:228)(cid:241)czenie dwukierunkowe, 34
magazyn, Patrz: magazyn danych
deserializacja, 88, 123, 135
.NET MVC, 143
@toranb, 143
A
Active Model Serializers, 42
adapter, 143
FixtureAdapter, 135, 136
LocalStorageAdapter, 136, 138, 145
RESTAdapter, 135, 144, 145
adres
IP, 31
URL, 31, 35, 38, 87, 88, 89
Ajax, 20, 123
akcja, 80, 81, 110
index, 155, 160
animacja, 169
Apache, 29
aplikacja, 66
debugowanie, 57
desktopowa, 16, 17
Ember, 52
inicjalizacja, 137
inicjator, 137, 138, 140
internetowa, 16, 17, 35
jednostronicowa, Patrz: SPA
kompilacja, 55
Ruby on Rails, Patrz: Ruby on Rails
serializacja stanu, 87
testowanie, 56
uruchamianie, 55
zarz(cid:241)dzaj(cid:241)ca list(cid:241) zada(cid:254), 65
application initializer, Patrz: aplikacja
inicjator
194
(cid:95)
Skorowidz
Kup książkęPoleć książkędetektor zdarze(cid:254), 110
Django, 143
dyrektywa Handlebars, 29
dziedziczenie, 23
E
EAK, 42, 145, 146, 175, 176, 179, 187
makieta API, 145
Echo Nest, 98, 99, 102, 103, 120
API, 104
EcmaScript 6, Patrz: ES6
Ember, 23, 24, 36, 51, 143
dokumentacja API, 95
instalowanie, 27, 47
komponent, 165, 166, 168
nazwa, 166
konwencja nazw, 59
uruchamianie, 48
zalety, 24
Ember App Kit, Patrz: EAK
Ember CLI, 43, 146
Ember Data, 43, 61, 126, 127,
130, 143, 184
odczyt, 160
Ember Data Store, 134
Ember Generator, 41
Ember Guides, 176
Ember Inspector, 57, 59, 61, 140
Ember Model, 127
Ember Persistence Fundation,
Patrz: EPF
Ember Rails, 42
Ember Tools, 42, 43
Ember.Observable, 113
Ember-Qunit, 189, 190
Enid, 98
EPF, 127
ES6, 43, 101, 147
ES6 Module Transpiler, 42, 43
Express.js, 26, 144, 145
F
fabryka, 70, 71
Fielding Roy, 144
Firebase, 143
Firefox, 57
FIXTURES, 191, 192
Florence Ryan, 136
formularz, 33
funkcja
click, 181
currentPath, 181
currentRouteName, 181
currentURL, 181
fillIn, 181
find, 181, 182
finds, 182
getJSON, 126
keyEvent, 181
moduleFor, 189, 190
moduleForComponent, 189
moduleForModel, 189, 193
pomocnicza, 181
test, 182
triggerEvent, 181
visit, 181, 182
gem, 151, 153
gemset, 151
Git, 43, 44
GitHub, 43
Grails, 143
Grunt, 45, 46, 54
G
H
History API, 87
HTML, 68
HTTP, 16, 17
Hypertext Transport Protocol,
Patrz: HTTP
I, J
iCloud, 16
implementacja, 21
IndexRoute, 76
interfejs u(cid:276)ytkownika wid(cid:276)et, 23
jquery -rails wersja, 159
Skorowidz
(cid:95)
195
Kup książkęPoleć książkęK
kontroler, 22, 34, 60, 81, 90, 107, 108,
Katz Yehuda, 88
komentarz, 32
klauzula build, 51
114, 155
nazwa, 97
Rails, 154
rozszerzanie, 114
L
lista nienumerowana, 77
LiveReload, 54
localhost, 32
M
magazyn danych, 134, 138, 140
mapa, 90, 92
domy(cid:264)lna, 92
termiczna, 169
mapowanie obiektowo-
-relacyjne, 25
metoda
.get, 113
.set, 113
all, 134
didInsertElement, 170
draw, 170
filter, 134
find, 134
findAll, 125
get, 125
getById, 134
getJSON, 102, 116
initialize, 137
model, 97, 100, 101, 102, 103, 113,
115, 116
pomocnicza, 177
render, 170
set, 125
setupController, 114
transitionTo, 129
MobileMe, 16
196
(cid:95)
Skorowidz
model, 21, 88, 90, 99, 155
tworzenie, 129
model-view-router-controler,
Patrz: MVRC
modu(cid:228)
ActiveModel::Serializers, 160
adapters/application, 147
cors, 185
MVC, 155
MVC Rails, 150
MVRC, 36
N
nag(cid:228)ówek, 69
Nginx, 29
Node Package Manager, Patrz: NPM
Node.js, 26
NPM, 45
O
obiekt, 21
App.name, 33
Application, 32, 34
JavaScript, 70
JSON, 123
localStorage, 136
okna, 177
Promise, 102
tworzenie, 100
window.isolatedContainer, 177
window.startApp, 177
obietnica, 101, 102, 113, 116, 126
object relational mapper, Patrz: ORM
object-oriented programming, Patrz: OOP
obrazu optymalizacja, 54
odno(cid:264)nik URL, Patrz: adres URL
OOP, 22
ORM, 25
P
pami(cid:246)(cid:232)
podr(cid:246)czna manifest, 54
wyciek, 19
Kup książkęPoleć książkęPHP, 143
plik
bower.json, 53, 136
Gemfile, 153
Gruntfile.js, 54
Handlebars.js, 69
handlebars.runtime.js, 71
index.html, 51
public/index.html, 154
statyczny, 35
pole
checkbox, 118
input, 33, 7
Pobierz darmowy fragment (pdf)