informatyka ajax on rails scott raymond ebook

background image

Wydawnictwo Helion
ul. Koœciuszki 1c
44-100 Gliwice
tel. 032 230 98 63

e-mail: helion@helion.pl

Ajax on Rails

Autor: Scott Raymond
T³umaczenie: Adrian Elczewski
ISBN: 978-83-246-1048-8
Tytu³ orygina³u:

Ajax on Rails

Format: B5, stron: 336

Zobacz, jak wykorzystaæ potencja³ technologii Ajax i Rails

w tworzeniu zaawansowanych aplikacji internetowych!

Jak u¿ywaæ platformy Rails do budowy dynamicznych aplikacji internetowych?

Jak szybko tworzyæ witryny ajaksowe, wykorzystuj¹c wydajne biblioteki?

Jak zwiêkszyæ komfort pracy u¿ytkowników Twoich aplikacji internetowych?

Ajax to olbrzymie mo¿liwoœci w zakresie tworzenia dynamicznych i interaktywnych
aplikacji internetowych, dzia³aj¹cych niemal tak szybko, jak tradycyjne programy.
Jednak lepsza jakoϾ witryn wymaga zwykle pisania bardziej skomplikowanego kodu
i, co za tym idzie, wiêkszych nak³adów pracy i czasu. Tak te¿ by³o do niedawna
w przypadku Ajaksa, ale obecnie, gdy wzros³a popularnoœæ tej technologii, a ona sama
dojrza³a, programiœci mog¹ korzystaæ z wielu bibliotek i platform, dziêki którym
tworzenie efektownych aplikacji internetowych sta³o siê niezwykle proste.

Ajax on Rails

to podrêcznik dla programistów, którzy chc¹ szybko i ³atwo budowaæ

wydajne aplikacje internetowe na bazie dwóch popularnych mechanizmów – technologii
Ajax oraz platformy Rails. Czytaj¹c go, dowiesz siê, w jaki sposób Ajax umo¿liwia
kreowanie funkcjonalnych i wygodnych w obs³udze witryn, a tak¿e nauczysz siê
b³yskawicznie stosowaæ tê technologiê w oparciu o biblioteki Prototype i scipt.aculo.us
oraz kompletn¹ platformê do tworzenia aplikacji internetowych, czyli Rails. Poznasz te¿
sposoby sprawnego diagnozowania aplikacji ajaksowych oraz zapewnisz im
bezpieczeñstwo i wydajnoœæ, aby udostêpniaæ swym klientom produkty najwy¿szej klasy.

Przegl¹d mechanizmów technologii Ajax

Dzia³anie platformy Rails

Ajaksowe przesy³anie danych za pomoc¹ biblioteki Prototype

Dodawanie efektów do witryn przy u¿yciu biblioteki scipt.aculo.us

Generowanie kodu JavaScript za pomoc¹ szablonów RJS

Zwiêkszanie u¿ytecznoœci aplikacji

Diagnozowanie aplikacji na platformie Rails

Zapewnianie bezpieczeñstwa programu

Zwiêkszanie wydajnoœci aplikacji

background image

3

Spis tre

ļci

Przedmowa .....................................................................................................................7

1. Wprowadzenie ..............................................................................................................11

Dla kogo jest ta ksiñĔka

11

Czym jest Ajax?

12

Czym jest Rails

18

„Twój Ajax w moim Rails”

21

Nabieranie prödkoĈci

21

Podsumowanie

27

2. Pierwsze kroki ..............................................................................................................29

Staromodny sposób

29

Prototype oraz inne biblioteki JavaScript

33

Rails pojawia siö na horyzoncie

35

Podsumowanie

40

3. Wprowadzenie do Prototype ....................................................................................... 41

Ustawianie sceny

41

ãñcza w Ajaksie

44

Formularze

48

Formularze w Ajaksie

51

Przyciski

52

Obserwatory formularza

54

Podsumowanie

55

4. Wprowadzenie do script.aculo.us ...............................................................................57

Efekty wizualne

57

Przeciñgnij i upuĈè

62

Podsumowanie

70

background image

4

_ Spis treļci

5. RJS .................................................................................................................................. 71

Instrukcje zamiast danych

71

Umieszczenie R w skrócie RJS

72

Przykäady z Ĕycia wziöte

85

Podsumowanie

87

6. U

żytecznoļë Ajaksa ......................................................................................................89

Zasady uĔytecznoĈci

90

Kontekst Internetu

94

UĔytecznoĈè w Internecie

97

Programowanie uwzglödniajñce róĔne przeglñdarki

103

Podsumowanie

107

7. Testowanie i usuwanie b

ĥýdów .................................................................................109

Usuwanie bäödów

110

Testowanie

122

Podsumowanie

134

8. Bezpiecze

ħstwo .......................................................................................................... 135

Zdrowy sceptycyzm: nie ufaè danym wejĈciowym uĔytkownika

135

Hashowanie haseä

144

Uciszanie logów

145

Polityka tej samej domeny

146

UĔywanie i naduĔywanie metod HTTP

148

Szyfrowanie i certyfikaty bezpieczeþstwa

151

Lista mailingowa o bezpieczeþstwie w Rails

152

Podsumowanie

152

9. Wydajno

ļë ................................................................................................................... 153

ćrodowiska projektowe i produkcyjne

153

Przechowywanie sesji

154

Buforowanie wyjĈcia

155

Pakowanie zasobów

160

Postöpowanie z däugo dziaäajñcymi zadaniami

162

Podsumowanie

164

10. Informator o Prototype .............................................................................................. 165

Wsparcie Ajaksa

166

Manipulacja DOM

172

Wbudowane rozszerzenia

185

background image

Spis tre

ļci _

5

11. Informator o script.aculo.us ....................................................................................... 199

Efekty wizualne

199

Przeciñgnij i upuĈè

209

Kontrolki

218

Rozszerzenia klasy element

226

Konstruktor DOM

228

Testowanie jednostkowe JavaScript

229

Metody narzödziowe

232

Przyk

ĥad A Quiz ...........................................................................................................233

Przyk

ĥad B Galeria zdjýë ............................................................................................ 249

Przyk

ĥad C Aplikacja wspóĥpracy w grupie ...............................................................267

Skorowidz ................................................................................................................... 315

background image

29

ROZDZIA

Ĥ 2.

Pierwsze kroki

O, Ajaksie! ZnowuĔ Ciö przyzywam.

Sofokles

W tym rozdziale gäównym zamysäem jest zrobienie rundki, maäymi kroczkami, po naprawdö
prostych przykäadach wykorzystania technologii Ajax. Rails dostarcza wiele moĔliwoĈci two-
rzenia zäoĔonych interakcji w technologii Ajax z uĔyciem bardzo maäej iloĈci kodu. Ale Ĕeby
zrozumieè, co siö dzieje „pod maskñ”, kaĔdy powinien byè obeznany z najniĔszym pozio-
mem dziaäania technologii Ajax (np. obiektem

XMLHttpRequest

). Po przyswojeniu treĈci tej

ksiñĔki tworzenie obiektu

XMLHttpRequest

za pomocñ biblioteki Prototype lub bez jej uĔycia

nie bödzie stanowiäo problemu. Czytelnik bödzie potrafiä z pomocñ Rails utworzyè proste inte-
rakcje w technologii Ajax bez pisania jakiegokolwiek kodu w JavaScripcie. Z tym zaäoĔeniem
zdobödziemy wiedzö na temat dziaäania pomocników Rails oraz dowiemy siö, jak wielu käo-
potów one oszczödzajñ.

Dla czytelników, którzy mieli okazjö zapoznaè siö z Rails i znajñ podstawy Ajaksa, ten roz-
dziaä bödzie okazjñ do odĈwieĔenia wiedzy, warto przynajmniej przyjrzeè siö przykäadom.

Staromodny sposób

ēeby rozpoczñè, wykonajmy najprostszñ rzecz do zrobienia z uĔyciem technologii Ajax: klik-
nijmy äñcze i zaprezentujmy odpowiedĒ z serwera — uĔywajñc bezpoĈrednio

XMLHttpRequest

,

bez pomocy Prototype czy pomocników Rails dla JavaScript.

UĔywanie

XMLHttpRequest

jest czösto opisywane jako coĈ wyjñtkowo trudnego. ãatwo zauwa-

Ĕyè, Ĕe po zdobyciu odrobiny doĈwiadczenia i poznaniu kilku nowych koncepcji nie jest to aĔ
tak zawiäe, jak moĔna by byäo siö spodziewaè na podstawie powszechnej opinii.

Rozpoczynanie projektu

Osoby, które nie stworzyäy przykäadu szkieletu Rails w poprzednim rozdziale, powinny zrobiè
to teraz, wpisujñc w wierszu poleceþ systemowych:

rails ajaxonrails
cd ajaxonrails
script/server

background image

30

_

Rozdzia

ĥ 2. Pierwsze kroki

Za pomocñ przeglñdarki naleĔy otworzyè stronö http://localhost:3000/ — powinien siö pojawiè ekran
powitalny Rails (dla celów przyszäego projektowania warto pamiötaè, Ĕe

script/server

uruchamia na porcie 3000 serwer HTTP). Teraz utwórzmy nowy kontroler, który nazwiemy

Chapter2Controller

, z akcjñ

myaction

. (Po uruchomieniu serwera w jednym terminalu

warto otworzyè inny).

script/generate controller chapter2 myaction

Generator Rails jest uĔywany do uzupeäniania szkieletu — przewaĔnie przez tworzenie
nowych kontrolerów i modeli. OczywiĈcie moĔna by w prosty sposób utworzyè
kontroler plików röcznie, ale uĔywanie generatora jest oszczödnoĈciñ pisania — co
zapobiega robieniu bäödów.

Generator ma takĔe inny skutek: za kaĔdym razem, gdy generuje siö kontroler, two-
rzony jest równieĔ wspóäpracujñcy z nim plik testów funkcjonalnych. To sposób Rails
na przypominanie, Ĕe testowanie jest waĔnñ czöĈciñ tworzenia aplikacji. Aby do-
wiedzieè siö wiöcej o dostöpnych generatorach i ich opcjach, naleĔy uruchomiè
script/generate bez Ĕadnych argumentów.

Teraz trzeba przejĈè do http://localhost:3000/chapter2/myaction. NaleĔy siö spodziewaè nowo utwo-
rzonego widoku jak na rysunku 2.1.

Rysunek 2.1. Nowo utworzony kontroler Rails i jego widok

Proszö zauwaĔyè, Ĕe domyĈlnie pierwsza czöĈè adresu URL determinuje kontroler, a druga akcjö
— metodö w ramach kontrolera. Teraz bödziemy edytowaè szablon dla tej akcji, do którego pro-
wadzi ĈcieĔka app/views/chapter2/myaction.rhtml. Dodajemy ten fragment HTML na dole pliku.

<p><a href="#" onclick="alert('Cze

Łð !');">Inline alert( )</a></p>

Jak moĔna zauwaĔyè, tworzymy akapit z prostym äñczem — ale zamiast standardowego atrybutu

href

uĔywamy

onclick

, do którego dostarczamy fragment kodu JavaScript do uruchomie-

nia. Po odĈwieĔeniu przeglñdarki i klikniöciu äñcza pojawi siö to, co przedstawia rysunek 2.2.

Wiöcej niĔ jedna czy dwie instrukcje wstawione do atrybutu

onclick

mogäyby szybko staè siö

niewygodne. PrzenieĈmy kod do osobnej funkcji JavaScript poprzez dodanie tego, co znaj-
duje siö poniĔej:

<p><a href="#" onclick="customAlert( ); ">Wywo

Īanie wĪasnej funkcji</a></p>

<script type="text/javascript">
function customAlert( ) {
alert('Powitanie z w

Ĩasnej funkcji.');

}
</script>

background image

Staromodny sposób

_

31

Rysunek 2.2. Prosta ramka ostrzegawcza

Proszö spróbowaè ponownie odĈwieĔyè stronö i zobaczyè, co siö stanie. Rezultat powinien
byè w zasadzie taki sam jak poprzednio.

Koniec rozgrzewki, teraz zajmiemy siö Ajaksem. (Ale proszö pamiötaè, Ĕe wciñĔ zaglñdamy
„pod maskö” — pod koniec tego rozdziaäu sporo zäoĔonoĈci Rails znacznie siö uproĈci). Po
pierwsze, musimy zdefiniowaè nowñ akcjö w kontrolerze, app/controllers/chapter2_controller.rb.
Teraz znajduje siö tam akcja

myaction

, wiöc nastöpnñ nazwijmy

myresponse

. Aby to zrobiè,

naleĔy utworzyè nowy plik, myresponse.rhtml w katalogu app/views/chapter2. Do zawartoĈci
pliku wprowadĒmy:

Powitanie z serwera.

ēeby mieè pewnoĈè, Ĕe wszystko dziaäa, proszö odwiedziè tö akcjö w swojej przeglñdarce
pod adresem http://localhost:3000/chapter2/myresponse — bödzie widoczne to, co przedstawia
rysunek 2.3.

Rysunek 2.3. Wynik akcji myresponse

Teraz wróèmy do myaction.rhtml i dodajmy kolejny fragment kodu HTML i JavaScript.

<p><a href="#" onclick="serverSideAlert( );">Wywo

Īanie funkcji po stronie serwera

</a></p>
<script type="text/javascript">
function serverSideAlert( ) {
var request = new XMLHttpRequest( );
request.open('get', '/chapter2/myresponse', false);
request.send(null);
alert(request.responseText);
}
</script>

background image

32

_

Rozdzia

ĥ 2. Pierwsze kroki

Za pomocñ przeglñdarki przejdĒmy z powrotem do http://localhost:3000/chapter2/myaction i klik-
nijmy nowe äñcze. JeĈli wszystko poszäo dobrze, powinna siö pojawiè wiadomoĈè z serwera,
taka jak na rysunku 2.4. Ostrzegamy, Ĕe ten przykäad nie bödzie dziaäaä we wczeĈniejszych niĔ
siódma wersjach Internet Explorera (ten problem podejmiemy póĒniej).

Rysunek 2.4. Rezultat pierwszego wywoäania w Ajaksie

Teraz do czegoĈ doszliĈmy! ēeby siö przekonaè, warto zerknñè na terminal, gdzie uruchomiony
jest

script/server

. Za kaĔdym razem, gdy klika siö „zajaksowane” äñcze, rejestrowane bö-

dzie nowe klikniöcie:

Processing Chapter2Controller#myresponse [GET]
Parameters: {"action"=>"myresponse", "controller"=>"chapter2"}
Completed in 0.00360 (278 reqs/sec) | Rendering: 0.00027 (7%) |
200 OK [http://localhost/chapter2/myresponse]

DuĔym problemem omawianego przykäadu jest to, Ĕe nie dziaäa on w jednej z najbardziej
rozpowszechnionych przeglñdarek, Internet Explorer 6. Przyczynñ jest obiekt ActiveX w im-
plementacji

XMLHttpRequest

Microsoftu (a wäaĈciwie dwa takie obiekty, co zaleĔy od wersji IE),

który musi byè tworzony w inny sposób. ēeby zlikwidowaè ten problem i sprawiè, aby nasz
przykäad dziaäaä poprawnie we wszystkich przeglñdarkach, tworzymy maäñ funkcjö. Oto wersja
przyjazna dla IE:

<p><a href="#" onclick="IEAlert( );">Wywo

Īanie serwera (dziaĪajîce pod IE)</a></p>

<script type="text/javascript">
function IEAlert( ) {
function getRequestObject( ) {
try { return new XMLHttpRequest( ) } catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
return false
}
var request = getRequestObject( );
request.open('get', '/chapter2/myresponse', false);
request.send(null);
alert(request.responseText);
}
</script>

Ta wersja jest taka sama jak wczeĈniejsza, z wyjñtkiem tego Ĕe zamiast tworzyè bezpoĈrednio
obiekt

XMLHttpRequest

, wywoäywana jest funkcja

getRequestObject()

, która wybiera moĔ-

liwñ opcjö. Ta funkcja robi uĔytek z deklaracji

try

w JavaScripcie, która jest wykorzystywana

background image

Prototype oraz inne biblioteki JavaScript

_

33

do wyäapywania wyjñtków i täumienia ich. (Ten przykäad wprowadza takĔe ideö deklarowa-
nia funkcji w funkcji, która moĔe byè nowoĈciñ dla niektórych programistów).

Dotychczas odrobinö oszukiwaliĈmy, poniewaĔ wywoäanie Ajaksa nie jest asynchroniczne.
Decyduje o tym trzeci parametr w metodzie

request.open()

. Do tej pory zakäadaliĈmy, Ĕe

wywoäanie nie byäo synchroniczne. W zwiñzku z tym

request.send()

byäo blokujñce — in-

terpreter JavaScript zatrzymywaä wykonywanie w tym wierszu i nie przechodziä do nastöpnego,
dopóki nie nadeszäa odpowiedĒ z serwera. ēeby sprawiè, aby wywoäanie byäo asynchroniczne,
musimy trochö zmieniè kod. Proszö dodaè ten fragment kodu do myaction.rhtml:

<p><a href="#" onclick="asyncAlert( )">Asynchroniczne wywo

Īanie serwera</a></p>

<script type="text/javascript">
function asyncAlert( ) {
function getRequestObject( ) {
try { return new XMLHttpRequest( ) } catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
return false
}
var request = getRequestObject( );
request.open('get', '/chapter2/myresponse');
request.onreadystatechange = function( ) {
if(request.readyState == 4) alert(request.responseText);
}
request.send(null);
}
</script>

We wszystkich poprzednich przykäadach wywoäywaliĈmy

request.send()

i natychmiast po-

tem odwoäywaliĈmy siö do

request.responseText()

. Teraz, gdy wysyäamy asynchroniczne

Ĕñdanie, odpowiedĒ niekoniecznie wraca po zakoþczeniu wywoäania. Aby rozwiñzaè ten pro-
blem, obiekt

XMLHttpRequest

ma atrybut

readyState

, który zmienia siö w czasie cyklu Ĕycia

Ĕñdania. Ma takĔe atrybut

onreadystatechange

, gdzie moĔna zdefiniowaè funkcjö, która bö-

dzie wywoäywana za kaĔdym razem, gdy status

readyState

bödzie siö zmieniaä. W tym przy-

käadzie definiujemy funkcjö, która sprawdza, czy

readyState

jest równy

4

(co oznacza, Ĕe

Ĕñdanie siö zakoþczyäo; kody

readyState

opisane sñ w peäni w rozdziale 3.), a jeĈli tak, wy-

Ĉwietla okienko z komunikatem. Opanowanie asynchronicznych zdarzeþ moĔe wymagaè trochö
czasu, ale jest zasadniczñ czöĈciñ röcznego programowania w Ajaksie.

Prototype oraz inne biblioteki JavaScript

Osoby, które dopiero zaczynajñ swojñ przygodö z Ajaksem, prawdopodobnie zaczöäy zauwaĔaè,

Ĕe pisanie w czystym Ajaksie, pozbawionym wsparcia dodatkowych bibliotek albo metod
pomocniczych, nie jest powszechne. W ogóle pomysä pisania wiöcej niĔ tuzina wierszy kodu
w celu stworzenia najprostszego moĔliwego zadania jest odpychajñcy.

Dziesiñtki bibliotek JavaScript wychodzñ z siebie, Ĕeby sprawiè, by Ajax byä äatwiejszy w obsäu-
dze. Jednñ z najbardziej popularnych jest Prototype, która stanowi czöĈè Rails. Bödziemy oma-
wiaè Prototype gruntownie w rozdziale 10., ale teraz przyjrzyjmy siö pewnym przykäadom.
Zanim zaczniemy coĈ innego, przeróbmy ponownie ostatni przykäad, tym razem uĔywajñc
Prototype. Oto nowy fragment do dodania:

<script src="/javascripts/prototype.js" type="text/javascript">
</script>
<p><a href="#" onclick="prototypeAlert( );">Wywo

Īanie funkcji z Prototype</a></p>

background image

34

_

Rozdzia

ĥ 2. Pierwsze kroki

<script type="text/javascript">
function prototypeAlert( ) {
new Ajax.Request('/chapter2/myresponse', { onSuccess: function(request) {
alert(request.responseText);
}})
}
</script>

Proszö zwróciè uwagö na pierwszy wiersz, gdzie wäñczamy äadowanie Ēródäa pliku prototype.js,
by móc z niego korzystaè na naszej stronie. Przy pierwszym tworzeniu szkieletu aplikacji Rails
kopia Prototype byäa umieszczona w katalogu public/javascripts. Wewnñtrz funkcji

prototype-

Alert()

pierwszy wiersz tworzy nowñ instancjö

Ajax.Request

, jednej z klas Prototype. Pierwszy

wywoäywany argument jest adresem URL, drugi — jest obiektem JavaScript — kolekcjñ par
kluczy – wartoĈci, które zachowujñ siö podobnie do map albo tablic asocjacyjnych w innych
jözykach programowania. W tym przypadku jedynñ wartoĈciñ jest

onSuccess

okreĈlajñca

funkcjö wywoäywanñ jako funkcja zwrotna.

Proszö zwróciè uwagö, iĔ w tym przykäadzie nie ma Ĕadnego kodu specyficznego dla obsäugi
wersji

XMLHttpRequest

dla przeglñdarki IE i Ĕadnej obsäugi kodów

readyState

. Prototype

obsäuguje te szczegóäy, udostöpniajñc programiĈcie duĔo czystsze API.

Dotychczas wszystkie nasze przykäady tworzyäy okno komunikatu

alert()

— które, w rze-

czywistych aplikacjach, prawdopodobnie nie jest najczöĈciej uĔywane. Znacznie czöĈciej do-
dawana jest nowa zawartoĈè strony albo modyfikowana dotychczasowa. Oto nowy fragment
do dodania:

<p><a href="#" onclick="updateElement( )">Uaktualnij element </a></p>
<p id="response"></p>
<script type="text/javascript">
function updateElement( ) {
new Ajax.Request('/chapter2/myresponse', { onSuccess: function(request) {
$('response').update(request.responseText);
}})
}
</script>

Proszö zauwaĔyè róĔnice miödzy powyĔszym a wczeĈniejszym przykäadem: dodany zostaä nowy
pusty element akapitu z atrybutem

id="response"

, który bödzie przechowywaä odpowiedĒ

otrzymanñ z serwera. Funkcja

onSuccess

zostaäa zmieniona, zamiast wywoäania

alert()

funkcja

ta umieszcza tekst odpowiedzi w elemencie

response

(uĔywajñc metody

update()

z biblio-

teki Prototype, która ustawia wäaĈciwoĈè elementu

innerHTML

). Symbol dolara jest faktycznie

nazwñ funkcji definiowanej przez Prototype, która pobiera ciñg znaków i zwraca element
HTML na podstawie tego ID. PoniewaĔ aktualizacja elementów HTML bödzie bardzo czösto
wykonywanym zadaniem, Prototype uäatwia to poprzez

Ajax.Updater.

Proszö to sprawdziè:

<p><a href="#" onclick="updater( )">Modernizuj za pomoc

î Ajax.Updater</a></p>

<p id="response2"></p>
<script type="text/javascript">
function updater( ) {
new Ajax.Updater('response2', '/chapter2/myresponse');
}
</script>

Funkcja $() w Prototype bödzie uĔywana bardzo czösto, z bliska wyglñda niezwy-
kle wartoĈciowo. Na pierwszy rzut oka jest prostym opakowaniem dla standardowej
metody DOM document.getElementById z nazwñ duĔo prostszñ do zapamiöta-
nia i sprawiajñcym wraĔenie skäadni JavaScript. Ale to wiöcej niĔ tylko opakowanie.

background image

Rails pojawia si

ý na horyzoncie

_

35

Przede wszystkim moĔe przyjñè dowolnñ liczbö argumentów, wiöc moĔna otrzymaè
kilka elementów jednoczeĈnie. Ponadto kaĔdy zwracany element jest automatycznie
rozszerzany o potöĔny zestaw metod omówionych w rozdziale 10.

Prawdopodobnie najbardziej istotne jest, Ĕe jeĈli przekaĔe siö do metody $() ciñg
znaków, zwróci ona element DOM z tym wäaĈnie ID. Ale jeĈli przekaĔe siö obiekt ja-
kiegokolwiek innego typu — powiedzmy element DOM — w prosty sposób zwróci
ten obiekt bez zmian. Wynikiem jest to, Ĕe moĔna uĔywaè $() z wartoĈciami, nawet
jeĈli nie jest siö pewnym, czy wartoĈci te sñ ciñgiem znaków czy elementem DOM, co
sprawia, Ĕe API JavaScript jest mniej podatne na bäödy.

Proszö zwróciè uwagö, Ĕe ten przykäad nie ma w sobie funkcji

onSuccess

, tutaj

Ajax.Updater

pobiera tylko dwa argumenty: ID elementu HTML, który ma byè zaktualizowany, i URL Ĕñ-
dania.

Ajax.Updater

wywoäuje URL i automatycznie tworzy funkcjö

onComplete

säuĔñcñ do

zaktualizowania okreĈlonego elementu DOM za pomocñ wartoĈci

response.Text

. Tak jak

w przypadku

Ajax.Request

, ostatni argument jest zestawem opcji. Jedna z nich jest nazwana

insertion

. Pozwala na pójĈcie duĔo dalej niĔ prosta zamiana zawartoĈci elementu, zamiast

tego umoĔliwia wstawienie zawartoĈci w rozmaitych punktach. Istniejñ cztery typy wstawia-
nia:

Before

,

Top

,

Bottom

oraz

After

. Na przykäad:

<p><a href="#" onclick="appendToElement( )">Dodaj do elementu</a></p>
<p id="response3"></p>
<script type="text/javascript">
function appendToElement( ) {
new Ajax.Updater('response3', '/chapter2/myresponse',
{ insertion:Insertion.Bottom });
}
</script>

Kiedy kliknie siö äñcze za pierwszym razem, odpowiedĒ z serwera bödzie dodana do tej stro-
ny tak jak poprzednio. Przy póĒniejszych klikniöciach, zamiast zastñpiè wczeĈniejszñ zawar-
toĈè, kolejne odpowiedzi bödñ doäñczane do poprzednich.

Proszö zauwaĔyè, Ĕe zdoäaliĈmy zredukowaè doĈè zäoĔone zachowanie do postaci funkcji z za-
ledwie jednñ instrukcjñ. Aby zatoczyè peäne koäo, moĔemy zredukowaè kod do postaci poje-
dynczego atrybutu

onclick

:

<p><a href="#" onclick="new Ajax.Updater('response4',
'/chapter2/myresponse', { insertion:Insertion.Bottom });">
Dodaj do elementu</a></p>
<p id="response4"></p>

Jak bödzie moĔna siö wkrótce przekonaè, jest to dokäadnie ten sam kod, który generujñ pomoc-
niki JavaScript w Rails.

Rails pojawia si

ý na horyzoncie

Rails dostarcza dogodnñ integracjö z Prototype w formie metod pomocników, które generujñ
wywoäania funkcji udostöpnianych przez Prototype. Odkryjemy, jak tworzyè Ajaksa bez pi-
sania jakiegokolwiek kodu w JavaScripcie, uĔywajñc metody pomocnika

link_to_remote()

.

Po pierwsze, musimy cofnñè siö odrobinö i dowiedzieè siö, jak Rails obsäuguje widoki.

background image

36

_

Rozdzia

ĥ 2. Pierwsze kroki

Podstawy ERb

Osoby, które kiedykolwiek korzystaäy z PHP, ColdFusion, ASP, JSP albo czegoĈ podobnego,
uznajñ, Ĕe jest to znajoma koncepcja. Wbudowany Ruby (Erb, ang. Embedded Ruby) pozwala
na äñczenie fragmentów Ruby z HTML-em. ERb definiuje zestaw specjalnych znaczników,
które sñ interpretowane jako Ruby; wszystko inne jest traktowane jako czysty HTML i zwra-
cane w nienaruszonej postaci. Oto te specjalne znaczniki:

<%= %>

Najcz

ýļciej używany, zawiera wyrażenie Ruby — którego wynik zwracany jest w miejscu znacznika.

<%= -%>

Dzia

ĥa tak jak powyższy, ale usuwa znaki nowego wiersza znajdujéce siý za tym znacznikiem, co pozwala na

czystsze zorganizowanie plików szablonów bez zb

ýdnych pustych miejsc w wynikowych dokumentach HTML.

<% %>

Przechowuje fragment kodu Ruby, ale nie zwraca niczego.

<% -%>

Dzia

ĥa tak jak powyższy, ale usuwa znaki nowego wiersza znajdujéce siý za tym znacznikiem.

<%# %>

To jest komentarz Ruby, który jest ignorowany i niczego nie zwraca.

Teraz spójrzmy na przykäad.

Czy pamiötasz dyskusjö o MVC z rozdziaäu 1.? Tutaj MVC zaczyna odgrywaè swojñ rolö.
Zwykle kontroler bödzie otrzymywaè Ĕñdanie wyĈwietlenia strony i przygotowywaè dane po-
trzebne dla widoku. W Rails dane te sñ umieszczane w zmiennych instancji (które sñ rozpoznawane
dziöki brzydkiemu znakowi

@

, od którego siö zaczynajñ ich nazwy). Proszö sobie zatem wy-

obraziè, Ĕe mamy takñ akcjö kontrolera:

def myaction
@foo = "Witaj,

Łwiecie!"

end

Akcja definiuje zmiennñ nazwanñ

@foo

i przypisuje jej äaþcuch znaków

Witaj,

Łwiecie!

. Nasz

szablon mógäby wiöc zawieraè coĈ takiego:

<%= @foo %>

I, gdy szablon jest wywoäywany,

<%= @foo %>

bödzie zastñpione przez

Witaj,

Łwiecie!

. Caä-

kiem oczywista sprawa. W praktyce przewaĔnie chce siö wykorzystaè zmiennñ w strukturze
HTML, np.:

<h1><%= @foo %></h1>

PoniewaĔ znacznik

<% %>

nie produkuje Ĕadnego wyjĈcia, najczöstsze jego uĔycie zwiñzane jest

ze strukturami kontrolnymi, takimi jak instrukcja

if

i iteracje

each

. W odróĔnieniu od innych

systemów szablonowych nie istnieje skäadnia specyficzna dla ERb dla tych konstrukcji; ERb
uĔywa zwyczajnych wyraĔeþ jözyka Ruby. Kilka przykäadów:

<% if @page_title %><h1><%= @page_title %></h1><% end %>
<% unless @names.empty? %>
<ul>
<% @names.each do |name| %><li><%= name %></li><% end %>
</ul>
<% end %>

Proszö spojrzeè na drugi wiersz. Zaczyna siö od wyraĔenia warunkowego

unless

— odpo-

wiednika Ruby dla

if not

. Proszö zwróciè teĔ uwagö na

@names.empty?

. Wszystkie tablice

Ruby korzystajñ z metody nazwanej

empty?

— zazwyczaj nazwy metod Ruby zwracajñcych

prawdö lub faäsz koþczñ siö znakiem zapytania. Ostatniñ sprawñ wartñ podkreĈlenia jest
czwarty wiersz. Wywoäanie metody

each

dla

@names

iteruje przez kaĔdy element tablicy, zatem

kod ten przejdzie caäñ tablicö

@names

i zwróci listö elementów w HTML dla kaĔdego imienia.

background image

Rails pojawia si

ý na horyzoncie

_

37

Uk

ĥad graficzny

Ukäad graficzny tworzñ specjalne szablony, które przechowujñ powszechnie uĔywane znacz-
niki dla wielokrotnie wykorzystywanych widoków. W innych systemach szablonowych jest to
czösto osiñgane poprzez tworzenie plików z szablonami nagäówka i stopki, które sñ wäñczane
do szablonu strony. Rails dziaäa odwrotnie — nagäówki i stopki sñ zdefiniowane w jednym
pliku wystroju graficznego, a stamtñd doäñczana jest treĈè strony. Pliki ukäadu graficznego sñ
przechowywane w app/views/layouts i domyĈlnie Rails najpierw poszuka tego, którego nazwa
jest taka sama jak aktualnego kontrolera, np. chapter2.rhtml. JeĈli Rails takiego pliku ukäadu
graficznego nie znajdzie, poszuka pliku nazwanego application.rhtml. ZawartoĈè pliku wystroju
graficznego moĔe wyglñdaè nastöpujñco:

<html>
<head>
<title>Moja Aplikacja Rails </title>
<%= javascript_include_tag "prototype" %>
</head>
<body>
<%= yield %>
</body>
</html>

NajwaĔniejszñ czöĈciñ, o której naleĔy wspomnieè, jest

<%= yield %>

. Jej zadaniem jest doäñ-

czenie kodu z szablonu widoku. Innymi säowy, spowoduje wstawienie kodu szablonu widoku
do pliku ukäadu graficznego. Proszö nie zapominaè o doäñczeniu tego wywoäania w pliku ukäadu
graficznego, bo w przeciwnym razie strony mogñ siö wydawaè puste.

Cz

ýļci

CzöĈci sñ podszablonami zaprojektowanymi dla fragmentów zäoĔonych ze znaczników, które
wykorzystywane sñ ponownie — albo np. chce siö je trzymaè w osobnym pliku, Ĕeby pliki
szablonów pozostaäy przejrzyste. CzöĈci sñ äatwe do zidentyfikowania, poniewaĔ ich nazwy
zawsze zaczynajñ siö od znaku podkreĈlenia. Na przykäad, moĔna stworzyè plik app/views/
chapter2/_person.rhtml
zawierajñcy:

<p><%= person.name %></p>

Z gäównego szablonu moĔna by byäo zaäñczyè takñ czöĈè:

<%= render :partial => "person" %>

Jest trochö magii wplecionej w przekazywanie zmiennych do czöĈci. PoniewaĔ ta czöĈè jest
nazwana „person”, gäówny szablon bödzie szukaä zmiennej instancji

@person

i przekazywaä jñ

do czöĈci jako zmiennñ lokalnñ

person

. Co jeĈli przykäadowa zmienna nie pasowaäaby do na-

zwy czöĈci? Wtedy trzeba jñ przekazaè jawnie jak tu:

<%= render :partial => "person", :locals => { :person => @adrian } %>

Wszystkie pary klucz – wartoĈè w tablicy asocjacyjnej

:locals

bödñ dostöpne jako zmienne

lokalne czöĈci.

DoĈè czöstym zastosowaniem czöĈci jest przeglñdanie tablicy obiektów i generowanie czöĈci
dla kaĔdego obiektu. Metoda

render

sprawia, Ĕe jest to proste dziöki opcji

:collection

. Na

przykäad:

<%= render :partial => "person", :collection => @people %>

background image

Czytaj dalej...

38

_

Rozdzia

ĥ 2. Pierwsze kroki

W tym przykäadzie gäówny szablon zawiera tablicö

@people

, która bödzie przeglñdana, a kaĔdy

element tablicy — zmienna lokalna

person

— zostanie przekazany do czöĈci.

DomyĈlnie szablony czöĈci powinny znajdowaè siö w tym samym katalogu co szablon gäówny.
Aby wykorzystaè czöĈci z poziomu innych kontrolerów, wystarczy dodaè nazwö katalogu jako
przedrostek. Na przykäad:

<%= render :partial => "chapter1/person" %>

Pomimo Ĕe gäównym szablonem jest chapter2/index.rhtml, czöĈè bödzie generowana na podstawie
pliku chapter1/_person.rhtml.

Pomocniki

Pomocniki sñ prostymi metodami Ruby dostöpnymi w szablonach, dostarczajñcymi innego
sposobu na to, by szablon pozostaä czysty i czytelny. Dla kaĔdego kontrolera tworzony jest
jeden plik pomocnika, zatem

Chapter2Controller

bödzie powiñzany z plikiem app/helpers/

chapter2_helper.rb. JeĈli chce siö mieè pomocnika dostöpnego dla wszystkich kontrolerów, na-
leĔy zdefiniowaè go w application_helper.rb.

Rails dostarcza szereg wbudowanych pomocników, które sñ powszechnie uĔywane — wäaĈci-
wie juĔ widzieliĈmy kilka z nich. W czöĈci „Ukäad graficzny” powyĔej czwarty wiersz jest wy-
woäaniem pomocnika:

<%= javascript_include_tag "prototype" %>

javascript_include_tag()

jest metodñ Ruby zdefiniowanñ przez Rails, która pobiera jako ar-

gument äaþcuch znaków (albo tablicö äaþcuchów znaków) i zwraca fragment HTML, jak np.:

<script src="/javascripts/prototype.js" type="text/javascript"></script>

Innym uĔytecznym pomocnikiem jest

h

, który zamienia HTML na czysty tekst. Na przykäad,

<%= h @foo %>

zapobiegnie zwróceniu znaków specjalnych HTML w wyjĈciu, zamieniajñc je na

encje, co jest waĔnym posuniöciem ze wzglödów bezpieczeþstwa przy wyĈwietlaniu danych
wprowadzonych przez uĔytkownika. Implikacjö tö bödziemy rozwaĔaè dokäadniej w roz-
dziale 8.

Byè moĔe najczöĈciej uĔywanym pomocnikiem jest

link_to

, który w prosty sposób generuje

äñcze. Na przykäad:

<%= link_to "Kliknij tutaj", :url => "/chapter2/myresponse" %>

Ten pomocnik zwraca:

<a href="/chapter2/myresponse">Kliknij tutaj</a>

.

Jest to caäkiem trywialny przykäad, ale interesujñcñ sprawñ jest to, Ĕe zamiast przekazywania
zwykäego adresu URL jako parametru moĔna przekazaè nazwö kontrolera, nazwö akcji i inne
parametry — a URL zostanie odpowiednio skonstruowany. Wspaniaäe tutaj jest to, Ĕe gdy
zmienia siö ĈcieĔki aplikacji, äñcza automatycznie zostanñ zmienione tak, aby pasowaäy do
zmienionych ĈcieĔek.

<%= link_to "Kliknij tutaj", :action => "myresponse" %>

WyjĈcie tej wersji jest takie samo jak powyĔej. Proszö zauwaĔyè, Ĕe nie okreĈlaliĈmy nazwy kon-
trolera — zostaäa ona pominiöta. Rails domyĈla siö, Ĕe chcemy uĔyè tego samego kontrolera,
w którym wäaĈnie siö „znajdujemy”.


Wyszukiwarka

Podobne podstrony:
informatyka ajax on java steven olson ebook
informatyka ruby on rails wprowadzenie wydanie ii bruce tate ebook
informatyka ajax wzorce projektowe michael mahemoff ebook
Ajax on Rails
informatyka ajax bezpieczne aplikacje internetowe christopher wells ebook
informatyka ajax implementacje shelley powers ebook
informatyka ajax i php tworzenie interaktywnych aplikacji internetowych wydanie ii bogdan brinzarea
An Informative Essay on Gandhi
Ajax on Java
informatyka html5 zaawansowane programowanie peter lubbers ebook

więcej podobnych podstron