informatyka javascript aplikacje www alex maccaw ebook

background image
background image

Tytuá oryginaáu: JavaScript Web Applications

Táumaczenie: Daniel Kaczmarek

ISBN: 978-83-246-3887-1

© 2012 Helion S.A.

Authorized Polish translation of the English edition of JavaScript Web Applications, 1st Edition
9781449303518 © 2011 Alex MacCaw

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.

Wydawnictwo HELION doáoĪyáo wszelkich staraĔ, by zawarte w tej ksiąĪce informacje byáy
kompletne i rzetelne. Nie bierze jednak Īadnej odpowiedzialnoĞci ani za ich wykorzystanie, ani za
związane z tym ewentualne naruszenie praw patentowych lub autorskich. Wydawnictwo HELION nie
ponosi 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/jascww.zip

Drogi Czytelniku!
JeĪeli chcesz oceniü tĊ ksiąĪkĊ, zajrzyj pod adres
http://helion.pl/user/opinie/jascww
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ść

background image

3

Spis tre"ci

Przedmowa ...............................................................................................................................9

1. MVC i klasy ....................................................................................................................17

Pocz tki

17

Nadawanie struktury

18

Czym jest MVC?

19

Model

19

Widok

20

Kontroler

21

Ku modularyzacji, tworzenie klas

22

Dodawanie funkcji do klas

23

Dodawanie metod do w#asnej biblioteki klas

24

Dziedziczenie klas przy u$yciu prototypu

25

Dodawanie dziedziczenia do biblioteki klas

26

Wywo#ywanie funkcji

27

Kontrola zasi%gu we w#asnej bibliotece klas

29

Dodawanie funkcji prywatnych

31

Biblioteki klas

32

2. Zdarzenia i ich nas#uchiwanie ....................................................................................35

Nas#uchiwanie zdarze&

35

Kolejno'( zdarze&

36

Anulowanie zdarze&

37

Obiekt zdarzenia Event

37

Biblioteki zdarze&

39

Zmiana kontekstu

40

Delegowanie zdarze&

40

W#asne zdarzenia

41

W#asne zdarzenia i modu#y rozszerzaj ce jQuery

41

Zdarzenia inne ni$ zdarzenia DOM

43

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4

Spis tre"ci

3. Modele i dane ..............................................................................................................47

MVC i przestrzenie nazw

47

Tworzenie ORM

48

Dziedziczenie przez prototypy

49

Dodawanie w#a'ciwo'ci ORM

50

Utrzymywanie rekordów

51

Dodawanie obs#ugi identyfikatorów

52

Adresowanie odwo#a&

53

)adowanie danych

54

Wplatanie danych

55

)adowanie danych przy u$yciu Ajax

55

JSONP

59

Bezpiecze&stwo $ da& mi%dzy domenami

59

Wype#nienie ORM danymi

60

Przechowywanie danych lokalnie

60

Dodanie mechanizmu przechowywania danych lokalnie do ORM

61

Przesy#anie nowych rekordów na serwer

63

4. Kontrolery i stany ........................................................................................................65

Wzorzec modu#u

66

Import zmiennych globalnych

66

Eksport zmiennych globalnych

66

Dodawanie kontekstu

67

Wydzielanie kodu do oddzielnej biblioteki

68

)adowanie kontrolerów po za#adowaniu dokumentu

69

Dost%p do widoków

70

Delegowanie zdarze&

72

Maszyny stanów

74

Routing

76

Korzystanie z hash value adresu URL

76

Wykrywanie zmian hash value

77

Ajax Crawling

77

Wykorzystanie API History HTML5

78

5. Widoki i szablony ........................................................................................................ 81

Dynamiczne generowanie widoków

81

Szablony

82

Pomocnicze funkcje obs#ugi szablonów

84

Przechowywanie szablonów

85

Wi zanie

86

Wi zanie modeli

87

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Spis tre"ci

5

6. Zarz$dzanie zale%no"ciami .........................................................................................89

CommonJS

90

Deklarowanie modu#u

90

Modu#y i przegl darka

91

Biblioteki #adowania modu#ów

92

Yabble

92

RequireJS

93

Opakowywanie modu#ów

94

Rozwi zania alternatywne wzgl%dem modu#ów

95

LABjs

96

FUBC

96

7. Praca z plikami ............................................................................................................. 97

Obs#uga w przegl darkach

97

Pobieranie informacji na temat plików

98

Kontrolka do przesy#ania plików na serwer

98

Przeci ganie i upuszczanie

99

Przeci ganie

100

Upuszczanie

101

Anulowanie domy'lnej obs#ugi przeci gania i upuszczania

102

Kopiowanie i wklejanie

103

Kopiowanie

103

Wklejanie

104

Czytanie plików

105

Du$e obiekty binarne oraz fragmenty pliku

106

W#asne przyciski przegl darki

107

)adowanie plików na serwer

107

*ledzenie post%pu operacji

109

Przesy#anie pliku na serwer przy u$yciu przeci gania i upuszczania

oraz biblioteki jQuery

111

Obszar upuszczania

111

Przesy#anie pliku na serwer

111

8. Praca w sieci w czasie rzeczywistym .........................................................................113

Historia dzia#ania w czasie rzeczywistym

113

WebSockets

114

Node.js i Socket.IO

118

Architektura czasu rzeczywistego

119

Odczuwana pr%dko'( dzia#ania

121

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

6

Spis tre"ci

9. Testowanie i usuwanie b#&dów ................................................................................ 123

Testy jednostkowe

125

Asercje

125

QUnit

126

Jasmine

129

Sterowniki

131

Testowanie niezale$ne

134

Zombie

134

Ichabod

136

Testowanie rozproszone

137

*wiadczenie wsparcia

137

Inspektory

138

Web Inspector

138

Firebug

140

Konsola

141

Funkcje pomocnicze konsoli

142

U$ywanie debuggera

143

Analiza $ da& sieciowych

144

Profilowanie i analiza czasu

145

10. Wdra%anie .................................................................................................................. 149

Wydajno'(

149

Wykorzystanie pami%ci podr%cznej

150

Minifikacja

152

Kompresja Gzip

153

Korzystanie z CDN

154

Audytory

155

Zasoby

156

11. Biblioteka Spine ..........................................................................................................157

Instalacja

157

Klasy

158

Tworzenie instancji

158

Rozszerzanie klas

159

Kontekst

160

Zdarzenia

161

Modele

161

Pobieranie rekordów

163

Zdarzenia modelu

163

Weryfikacja poprawno'ci

164

Zapisywanie

164

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Spis tre"ci

7

Kontrolery

166

Wskazywanie kontekstu

167

W#a'ciwo'( elements

167

Delegowanie zdarze&

168

Zdarzenia kontrolera

168

Zdarzenia globalne

169

Wzorzec Render

170

Wzorzec Element

170

Aplikacja do zarz dzania danymi kontaktowymi

171

Model Contact

173

Kontroler Sidebar

173

Kontroler Contacts

175

Kontroler App

178

12. Biblioteka Backbone .................................................................................................. 179

Modele

180

Modele i atrybuty

180

Kolekcje

181

Kontrola kolejno'ci elementów w kolekcji

183

Widoki

183

Generowanie widoków

184

Delegowanie zdarze&

184

Wi zanie i kontekst

185

Kontrolery

186

Synchronizacja z serwerem

188

Wype#nianie kolekcji

189

Po stronie serwera

189

Implementacja w#asnej logiki

190

Aplikacja do zarz dzania list rzeczy do zrobienia

192

13. Biblioteka JavaScriptMVC ......................................................................................... 199

Konfiguracja

200

Klasy

200

Tworzenie instancji

200

Wywo#ywanie metody bazowej

201

Okre'lanie kontekstu

201

Dziedziczenie statyczne

201

Introspekcja

202

Przyk#adowy model

202

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

8

Spis tre"ci

Model

203

Atrybuty i dane obserwowalne

203

Rozszerzanie modeli

205

Metody ustawiaj ce warto'ci

205

Warto'ci domy'lne

206

Metody pomocnicze

206

Enkapsulacja us#ug

207

Przekszta#canie typów

209

Zdarzenia CRUD

210

Wykorzystanie w widokach szablonów dzia#aj cych po stronie klienta

210

Sposób u$ycia

211

Modyfikatory jQuery

211

)adowanie widoku ze znacznika skryptu

212

$.View i subszablony

212

Obiekty wstrzymane

212

Pakowanie, #adowanie wst%pne i wydajno'(

213

$.Controller: fabryka modu#ów rozszerzaj cych jQuery

213

Informacje ogólne

215

Tworzenie instancji kontrolera

216

Wi zanie zdarze&

216

Akcje szablonowe

217

Kompletne rozwi zanie: abstrakcyjna lista czynno'ci CRUD

218

A. Wprowadzenie do biblioteki jQuery ........................................................................ 221

B. Rozszerzenia CSS ....................................................................................................... 231

C. Przegl$d CSS3 ............................................................................................................235

Skorowidz .............................................................................................................................255

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

47

ROZDZIA* 3.

Modele i dane

Gdy aplikacja ma utrzymywa( stan na kliencie, jednym z wyzwa& stoj cym przed programi-
st jest zapewnienie odpowiedniego zarz dzania danymi. Standardowo w momencie wy-
wo#ania strony dane pobiera si% bezpo'rednio z bazy danych, a wynik ich przetwarzania
umieszcza si% bezpo'rednio na stronie. Jednak w stanowych aplikacjach JavaScript proces za-
rz dzania danymi przebiega zupe#nie inaczej. Nie obowi zuje w nich model wywo#anie-
odpowied/, nie s tak$e dost%pne zmienne na serwerze. Dane s za to pobierane zdalnie i tym-
czasowo przechowywane po stronie klienta.

Wprawdzie zaimplementowanie odpowiedniego mechanizmu mo$e by( do'( trudnym za-
daniem, jednak uzyska si% dzi%ki temu co najmniej kilka korzy'ci. Na przyk#ad dost%p do da-
nych znajduj cych si% po stronie klienta jest praktycznie natychmiastowy, tak jakby dane po-
bierane by#y z pami%ci. Mo$e to zdecydowanie poprawi( dzia#anie interfejsu aplikacji, poniewa$
ka$da czynno'( u$ytkownika skutkuje natychmiastowym zwróceniem wyniku. Dzi%ki temu
aplikacja znajduje zdecydowanie wi%ksze uznanie u u$ytkowników.

Aby odpowiednio skonstruowa( mechanizm przechowywania danych po stronie klienta,
trzeba najpierw szczegó#owo przeanalizowa( wszystkie okoliczno'ci. Zadanie naje$one jest
ró$norodnymi przeszkodami i pu#apkami, w które wpadaj zw#aszcza pocz tkuj cy progra-
mi'ci — szczególnie gdy ich aplikacje coraz bardziej si% rozrastaj . W tym rozdziale zoba-
czymy, jak w najbardziej efektywny sposób zaimplementowa( przechowywanie danych po
stronie klienta. Wskazane zostan tak$e najbardziej zalecane wzorce i praktyki.

MVC i przestrzenie nazw

Aby opracowa( tak architektur% aplikacji, która b%dzie przejrzysta i #atwa w utrzymaniu,
trzeba przede wszystkim zapewni( pe#n separacj% widoków aplikacji, jej stanu i danych.
W przypadku wykorzystania wzorca MVC zarz dzanie danymi odbywa si% w modelu („M”
w nazwie MVC). Modele powinny by( roz# czne wzgl%dem widoków i kontrolerów. Natomiast
logika wyznaczaj ca sposób manipulowania danymi oraz odpowiedzialna za zachowanie
aplikacji powinna by( osadzona w modelu oraz oznaczona odpowiedni przestrzeni nazw.

W JavaScripcie odpowiedni przestrze& nazw dla funkcji i zmiennych mo$na zapewni( przez
uczynienie ich w#a'ciwo'ciami obiektu. Na przyk#ad:

var User = {
records: [ /* ... */ ]
};

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

48

Rozdzia# 3. Modele i dane

Tablica u$ytkowników ma teraz odpowiedni przestrze& nazw

User.records

. Funkcje zwi za-

ne z obs#ug u$ytkowników równie$ mog nale$e( do przestrzeni nazw wyznaczanej przez
model

User

. Mo$na na przyk#ad zaimplementowa( funkcj%

fetchRemote()

, która b%dzie pobiera(

z serwera dane u$ytkownika:

var User = {
records: [],
fetchRemote: function(){ /* ... */ }
};

Umieszczenie wszystkich w#a'ciwo'ci modelu w przestrzeni nazw zapewni, $e nie wyst pi
$adne konflikty, a jednocze'nie utrzymana zostanie zgodno'( z paradygmatem MVC. Poza
tym zmniejszy si% zagro$enie, $e tworzony kod /ród#owy zamieni si% z biegiem czasu w nie-
zrozumia# spiral% funkcji i wywo#a& zwrotnych.

Zakres wykorzystania przestrzeni nazw mo$na jeszcze pog#%bi( i umie'ci( wszystkie funkcje
operuj ce na instancjach u$ytkowników w rzeczywistych obiektach u$ytkowników. Przyjmij-
my, $e na rekordzie u$ytkownika zaimplementowana jest funkcja

destroy()

. Odnosi si% ona

do konkretnego u$ytkownika, zatem powinna by( wywo#ywana na instancji obiektu

User

:

var user = new User;
user.destroy()

Aby osi gn ( zamierzony efekt, nale$y uczyni( z

User

klas%, a nie zwyk#y obiekt:

var User = function(atts){
this.attributes = atts || {};
};

User.prototype.destroy = function(){
/* ... */
};

Natomiast wszelkie funkcje i w#a'ciwo'ci, które nie dotycz konkretnego u$ytkownika, mog
by( w#a'ciwo'ciami bezpo'rednio obiektu

User

:

User.fetchRemote = function(){
/* ... */
};

Wi%cej ciekawych informacji na temat przestrzeni nazw mo$na znale/( na blogu Petera
Michaux, który opublikowa# bardzo ciekawy artyku# na ten w#a'nie temat (http://michaux.ca/
articles/javascript-namespacing

).

Tworzenie ORM

Biblioteki odwzorowa& obiektowo-relacyjnych, czyli ORM, s zwykle wykorzystywane w j%-
zykach programowania innych ni$ JavaScript. Stanowi one jednak bardzo przydatne narz%-
dzia do zarz dzania danymi, a tak$e znacznie u#atwiaj u$ycie modeli w aplikacji JavaScript.
Za pomoc ORM mo$na na przyk#ad powi za( model ze zdalnym serwerem — w wyniku
takiego powi zania wszelkie zmiany w instancjach modelu b%d wysy#ane w tle do serwera
w ramach wywo#a& Ajax. Mo$na tak$e powi za( instancj% modelu z elementem HTML, dzi%ki
czemu wszelkie zmiany w instancji modelu spowoduj odpowiedni zmian% w widoku.
Przyk#ady te zostan rozwini%te nieco pó/niej, a na razie zobaczmy, jak tworzy si% ORM.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Tworzenie ORM

49

Zasadniczo ORM jest po prostu warstw obiektów opakowuj c jakie' dane. Standardowo
ORM stanowi warstw% abstrakcji dla baz danych SQL, jednak w naszym przypadku ORM
b%dzie po prostu warstw abstrakcji dla typów danych JavaScriptu. Zalet takiej dodatkowej
warstwy jest to, $e podstawowy zbiór danych mo$na rozszerzy( o dodatkowe rozwi zania
przez dodanie w#asnych funkcji i w#a'ciwo'ci. Dzi%ki temu mo$na dodawa( mechanizmy wery-
fikacji poprawno'ci albo utrzymywania danych, obserwatory czy wywo#ania zwrotne do ser-
wera, a jednocze'nie nadal mie( mo$liwo'( wielokrotnego wykorzystywania kodu /ród#owego.

Dziedziczenie przez prototypy

Do stworzenia naszej w#asnej biblioteki ORM wykorzystamy

Object.create()

, co jest podej-

'ciem nieco odmiennym od przyk#adów opisywanych w rozdziale 1, w których korzystali-
'my z klas. Nowe podej'cie pozwoli nam jednak na skorzystanie z dziedziczenia przez pro-
totypy zamiast u$ywania funkcji konstruktorów i s#owa kluczowego

new

.

Funkcja

Object.create()

przyjmuje jeden argument — obiekt prototypu — i zwraca nowy

obiekt z przekazanym obiektem prototypu. Inaczej mówi c, przekazuje si% do niej obiekt,
a funkcja zwraca nowy obiekt, potomny po obiekcie przekazanym.

Funkcja

Object.create()

zosta#a dopiero niedawno dodana do specyfikacji ECMAScript, 5th

Edition i dlatego jeszcze nie wszystkie przegl darki j obs#uguj — nale$y do nich mi%dzy
innymi IE. Nie jest to jednak wielki problem, poniewa$ w razie potrzeby obs#ug% tej funkcji
mo$na zaimplementowa( samemu:

if (typeof Object.create !== "function")
Object.create = function(o) {
function F() {}
F.prototype = o;
return new F();
};

Powy$szy przyk#ad pochodzi z artyku#u Douglasa Crockforda na temat dziedziczenia przez
prototypy (http://javascript.crockford.com/prototypal.html). Warto si% z nim zapozna(, aby lepiej
pozna( mechanizmy rz dz ce prototypami i dziedziczeniem w j%zyku JavaScript.

Utworzymy teraz obiekt

Model

, którego zadaniem b%dzie tworzenie nowych modeli i instancji:

var Model = {
inherited: function(){},
created: function(){},

prototype: {
init: function(){}
},

create: function(){
var object = Object.create(this);
object.parent = this;
object.prototype = object.fn = Object.create(this.prototype);

object.created();
this.inherited(object);
return object;
},

init: function(){
var instance = Object.create(this.prototype);

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

50

Rozdzia# 3. Modele i dane

instance.parent = this;
instance.init.apply(instance, arguments);
return instance;
}
};

Programistów, którzy nie poznali dotychczas funkcji

Object.create()

, definicja

Model

mo$e

nieco zniech%ca(, wi%c roz#o$ymy j na czynniki pierwsze. Funkcja

create()

zwraca nowy

obiekt, który dziedziczy po obiekcie

Model

. W ten sposób tworzone b%d nowe modele. Funkcja

init()

zwraca natomiast nowy obiekt, który dziedziczy po

Model.prototype

— czyli instancj%

obiektu

Model

:

var Asset = Model.create();
var User = Model.create();

var user = User.init();

Dodawanie w#a"ciwo"ci ORM

Je'li teraz do

Model

dodamy w#a'ciwo'ci, stan si% one dost%pne we wszystkich modelach

potomnych:

// Dodanie w%a&ciwo&ci obiektu
jQuery.extend(Model, {
find: function(){}
});

// Dodanie w%a&ciwo&ci instancji
jQuery.extend(Model.prototype, {
init: function(atts) {
if (atts) this.load(atts);
},

load: function(attributes){
for(var name in attributes)
this[name] = attributes[name];
}
});

Metoda

jQuery.extend()

odpowiada wykonaniu p%tli

for

i wykonaniu w niej r%cznego kopio-

wania w#a'ciwo'ci. Tak w#a'nie post%pujemy w funkcji

load()

. Teraz w#a'ciwo'ci obiektu

i instancji s propagowane w dó#, do konkretnych modeli:

assertEqual( typeof Asset.find, "function" );

W praktyce liczba dodawanych w#a'ciwo'ci b%dzie do'( znaczna, dlatego najlepiej jest od razu
zawrze( w obiekcie

Model

funkcje

extend()

i

include()

:

var Model = {
/* ... ci*cie ... */

extend: function(o){
var extended = o.extended;
jQuery.extend(this, o);
if (extended) extended(this);
},

include: function(o){
var included = o.included;
jQuery.extend(this.prototype, o);
if (included) included(this);

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Tworzenie ORM

51

}
};

// Dodanie w%a&ciwo&ci obiektu
Model.extend({
find: function(){}
});

// Dodanie w%a&ciwo&ci instancji
Model.include({
init: function(atts) { /* ... */ },
load: function(attributes){ /* ... */ }
});

Mo$na ju$ zatem tworzy( nowe zasoby i ustawia( ich atrybuty:

var asset = Asset.init({name: "foo.png"});

Utrzymywanie rekordów

Potrzebny jest równie$ mechanizm utrzymywania rekordów, to znaczy zapami%tywania od-
wo#a& do utworzonych instancji, aby móc z nich korzysta( w pó/niejszym czasie. Do tego
celu wykorzystany zostanie obiekt

records

ustawiony w modelu

Model

. Obiekt b%dzie dodawany

do modelu w momencie zapisywania instancji modelu i usuwany z obiektu modelu, gdy usu-
wana b%dzie instancja modelu:

// Obiekt z zapisanymi zasobami
Model.records = {};

Model.include({
newRecord: true,

create: function(){
this.newRecord = false;
this.parent.records[this.id] = this;
},

destroy: function(){
delete this.parent.records[this.id];
}
});

A w jaki sposób mo$na zmienia( istniej c instancj%? To proste — wystarczy zmieni( odwo-
#anie do obiektu:

Model.include({
update: function(){
this.parent.records[this.id] = this;
}
});

Warto tak$e zaimplementowa( wygodn funkcj% odpowiedzialn za zapisywanie instancji,
tak by nie trzeba by#o pó/niej sprawdza(, czy instancja zosta#a zapisana ju$ wcze'niej albo
czy trzeba t% instancj% utworzy(:

// Zapisanie obiektu do records i zapami*tanie odwo%ania do obiektu
Model.include({
save: function(){
this.newRecord ? this.create() : this.update();
}
});

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

52

Rozdzia# 3. Modele i dane

Wreszcie dobrze te$ zaimplementowa( funkcj%

find()

, która b%dzie wyszukiwa( zasoby o wska-

zanym identyfikatorze:

Model.extend({
// Znalezienie zasobu o danym ID lub rzucenie wyj1tku
find: function(id){
return this.records[id] || throw("Rekord nieznany");
}
});

ORM w najprostszej postaci jest ju$ gotowy, mo$na go zatem wykorzysta( w praktyce:

var asset = Asset.init();
asset.name = "taki sam, taki sam";
asset.id = 1
asset.save();

var asset2 = Asset.init();
asset2.name = "ale inny";
asset2.id = 2;
asset2.save();

assertEqual( Asset.find(1).name, "taki sam, taki sam" );

asset2.destroy();

Dodawanie obs#ugi identyfikatorów

Obecnie za ka$dym razem, gdy zapisywany jest rekord, trzeba r%cznie zdefiniowa( jego
identyfikator ID. To przykry obowi zek, ale na szcz%'cie mo$na to zadanie zautomatyzowa(.
Najpierw potrzebny jest jaki' mechanizm generowania identyfikatorów — mo$e nim by( ge-
nerator identyfikatorów GUID (ang. Globally Unique Identifier). Z technicznego punktu wi-
dzenia JavaScript nie mo$e generowa( pe#noprawnych, 128-bitowych identyfikatorów GUID
z powodu ogranicze& API, które potrafi generowa( tylko liczby pseudolosowe. Generowanie
prawdziwie losowych identyfikatorów jest zawsze trudnym zadaniem i systemy operacyjne
obliczaj je na podstawie adresu MAC, pozycji myszy, sum kontrolnych BIOS-u, a nawet na
podstawie pomiarów szumu elektrycznego albo produktów rozpadu radioaktywnego; cza-
sami wr%cz u$ywa si% lamp z zawarto'ci cieczy oraz wosku, które po rozgrzaniu tworz
ró$ne efekty kolorystyczne! Jednak natywna funkcja

Math.random()

, cho( pseudolosowa, w zu-

pe#no'ci nam wystarczy.

Robert Kieffer napisa# prosty i zwi%z#y generator identyfikatorów GUID, który za pomoc funkcji

Math.random()

generuje GUID pseudolosowe (http://www.broofa.com/2008/09/javascript-uuid-function/).

Generator jest na tyle prosty, $e mo$emy jego kod /ród#owy zaprezentowa( w ca#o'ci:

Math.guid = function(){
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
}).toUpperCase();
};

Mamy wi%c funkcj%, która generuje identyfikatory GUID, zatem zintegrowanie jej z ORM nie
nastr%czy ju$ trudno'ci. Wystarczy w tym celu zmieni( kod funkcji

create()

:

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Adresowanie odwo#a-

53

Model.extend({
create: function(){
if ( !this.id ) this.id = Math.guid();
this.newRecord = false;
this.parent.records[this.id] = this;
}
});

Od teraz ka$dy nowo utworzony rekord b%dzie mia# identyfikator w postaci losowego GUID:

ar asset = Asset.init();
asset.save();

asset.id //=> "54E52592-313E-4F8B-869B-58D61F00DC74"

Adresowanie odwo#a-

Uwa$ni Czytelnicy zapewne zwrócili uwag% na b# d zwi zany z odwo#aniami w naszej bi-
bliotece ORM. Nie klonujemy instancji ani wtedy, gdy zostaj zwrócone przez

find()

, ani

w momencie ich zapisywania, przez co je'li zmienimy któr ' z ich w#a'ciwo'ci, zmiana
dotknie oryginalnego zasobu. Jest to powa$ny problem, poniewa$ oczekujemy, $e zasoby
b%d si% zmienia( jedynie po wykonaniu funkcji

update()

:

var asset = new Asset({name: "foo"});
asset.save();

// Asercja przekazuje prawid%owo
assertEqual( Asset.find(asset.id).name, "foo" );

// Zmiana w%a&ciwo&ci bez wywo%ywanai update()
asset.name = "wem";

// O nie! Asercja koHczy si* niepowodzeniem, poniewaJ nazw1 jest teraz "wem"
assertEqual( Asset.find(asset.id).name, "foo" );

Aby wyeliminowa( b# d, w trakcie dzia#ania

find()

utworzymy nowy obiekt. Ponadto konieczne

b%dzie zduplikowanie obiektu zawsze wtedy, gdy dojdzie do utworzenia lub zmiany rekordu:

Asset.extend({
find: function(id){
var record = this.records[id];
if ( !record ) throw("Rekord nieznany");
return record.dup();
}
});

Asset.include({
create: function(){
this.newRecord = false;
this.parent.records[this.id] = this.dup();
},

update: function(){
this.parent.records[this.id] = this.dup();
},

dup: function(){
return jQuery.extend(true, {}, this);
}
});

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

54

Rozdzia# 3. Modele i dane

Jest jeszcze jeden problem —

Model.records

to obiekt, który jest wspó#u$ytkowany przez

wszystkie modele:

assertEqual( Asset.records, Person.records );

Daje to niepo$ dany efekt wymieszania ze sob wszystkich rekordów:

var asset = Asset.init();
asset.save();

assert( asset in Person.records );

Rozwi zanie polega na tym, by za ka$dym razem, gdy tworzony jest nowy model, ustawia(
te$ nowy obiekt

records

.

Model.created()

jest wywo#aniem zwrotnym do tworzenia nowego

obiektu, dlatego mo$na w nim ustawia( dowolne obiekty dotycz ce tego w#a'nie modelu:

Model.extend({
created: function(){
this.records = {};
}
});

*adowanie danych

Je'li aplikacja internetowa dzia#a w jakiej' cz%'ci poza przegl dark , konieczne jest umo$li-
wienie #adowania danych zdalnie z serwera. Zazwyczaj w trakcie uruchamiania aplikacji #a-
dowany jest jaki' podzbiór danych, a po wykonaniu okre'lonych czynno'ci przez u$ytkow-
nika aplikacja #aduje kolejne potrzebne dane. Zale$nie od rodzaju aplikacji i ilo'ci danych
komplet danych mo$na pozyskiwa( od razu w momencie pierwszego #adowania strony. Jest
to przypadek idealny, poniewa$ wówczas u$ytkownicy nie b%d ju$ musieli czeka( na za#a-
dowanie dodatkowych danych. Jednak w przypadku wi%kszo'ci aplikacji rozwi zanie takie
nie wchodzi w gr%, poniewa$ zbiór potrzebnych danych jest zbyt du$y, by bez problemu
zmie'ci# si% w pami%ci dost%pnej dla przegl darki.

Tylko dzi%ki za#adowaniu danych od razu przy starcie aplikacji b%dzie mo$na zapewni(
u$ytkownikom komfort pracy z ni , a czas odpowiedzi zredukowa( do minimum. Istnieje
jednak istotna ró$nica mi%dzy pocz tkowym #adowaniem danych, które rzeczywi'cie s po-
tem wykorzystywane, a #adowaniem danych nadmiarowych, które nigdy nie zostan u$yte.
Trzeba zatem przewidzie(, których danych u$ytkownicy b%d potrzebowa(, albo dokona(
odpowiednich pomiarów ju$ w trakcie pracy aplikacji.

Na przyk#ad je'li #adowana jest lista stronicowana, to dlaczego nie za#adowa( od razu za-
warto'ci nast%pnej strony, aby prze# czanie mi%dzy stronami nast%powa#o od razu? Albo,
co da#oby jeszcze lepszy efekt, po prostu wy'wietli( d#ug list% i automatycznie #adowa(
i wstawia( do niej dane, gdy u$ytkownik b%dzie t% list% przewija# (s#u$y do tego wzorzec nie-
sko&czonego suwaka). Im mniejsze b%dzie opó/nienie widoczne dla u$ytkownika, tym lepiej.

Nale$y zapewni(, $e w trakcie pobierania nowych danych interfejs u$ytkownika nie b%dzie
si% blokowa#. Warto wy'wietli( jaki' wska/nik post%pu #adowania danych, ale ca#o'( interfej-
su powinna przez ca#y czas by( dost%pna dla u$ytkownika. Liczba sytuacji, w której b%dzie
dochodzi#o do zablokowania interfejsu, powinna by( jak najmniejsza, a najlepiej, by w ogóle
do tego nie dochodzi#o.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

*adowanie danych

55

Dane mo$na wplata( w definicj% strony b d/ pobiera( je w oddzielnych $ daniach HTTP za
pomoc Ajax lub JSONP. Polecam raczej to drugie rozwi zanie, poniewa$ wplatanie w kod
strony du$ych ilo'ci danych powoduje znaczne zwi%kszenie rozmiaru strony, natomiast
dzi%ki pobieraniu danych równolegle z #adowaniem strony skraca si% ca#kowity czas jej #a-
dowania. Technologie AJAX i JSONP pozwalaj dodatkowo umieszcza( strony HTML w pa-
mi%ci podr%cznej, dzi%ki czemu nie trzeba ich #adowa( na nowo przy ka$dym kolejnym
wywo#aniu.

Wplatanie danych

Nie polecam stosowania tego podej'cia z powodów opisanych w poprzednim akapicie, jed-
nak technika wplatania danych mo$e by( w niektórych okoliczno'ciach przydatna, zw#aszcza
gdy #adowane s niewielkie zbiory danych. Technika wplatania danych ma t% niezaprzeczaln
zalet%, $e bardzo prosto si% j implementuje.

Wystarczy w tym celu generowa( obiekt JSON bezpo'rednio w kodzie strony. W technologii
Ruby on Rails odpowiednie rozwi zanie mia#oby tak posta(:

<script type="text/javascript">
var User = {};
User.records = <%= raw @users.to_json %>;
</script>

W przedstawionym kodzie wykorzystano znaczniki ERB, aby zwróci( przetworzone przez
JSON dane u$ytkownika. Metoda

raw

zapobiega wstawianiu znaków ucieczki przez JSON.

W wyniku przetworzenia strony jej kod HTML b%dzie wygl da# tak:

<script type="text/javascript">
var User = {};
User.records = [{"first_name": "Alex"}];
</script>

JavaScript mo$e przetwarza( dane JSON bez ich dodatkowego przekszta#cania, poniewa$
JSON ma tak sam struktur% jak obiekty j%zyka JavaScript.

*adowanie danych przy u%yciu Ajax

)adowanie danych przy u$yciu Ajax to chyba pierwsza metoda #adowania zdalnych danych,
która przychodzi na my'l programistom, gdy mowa o wywo#aniach w tle. To nie przypadek:
technologia ta zosta#a wypróbowana, przetestowana i udost%pniona we wszystkich wspó#-
czesnych przegl darkach. Ajax nie jest oczywi'cie pozbawiony wad — historia rozwoju tej
technologii, dla której nie istnia#y $adne standardy, zako&czy#a si% powstaniem niespójnych API.
Przez to w#a'nie, oraz ze wzgl%du na wymogi bezpiecze&stwa przegl darek internetowych,
#adowanie danych z innych domen jest zadaniem do'( skomplikowanym.

Programistom, którzy potrzebuj krótkiego wprowadzenia do technologii Ajax i klasy

XMLHttpRequest

,

warto poleci( artyku# Getting Started w witrynie Mozilla Developer (https://developer.mozilla.org/
en/Ajax/Getting_Started

). Z du$ym prawdopodobie&stwem mo$na za#o$y(, $e i tak wi%kszo'(

programistów ostatecznie wykorzysta bibliotek%, na przyk#ad jQuery, która b%dzie udost%pnia(
warstw% abstrakcji nad API Ajax i ukrywa( przed programist ró$nice w obs#udze technologii
mi%dzy poszczególnymi przegl darkami. Dlatego w tym punkcie b%dzie mowa o API biblioteki
jQuery, a nie o samej klasie

XMLHttpRequest

.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

56

Rozdzia# 3. Modele i dane

API Ajax biblioteki jQuery zawiera jedn funkcj% niskiego poziomu o nazwie

jQuery.ajax()

oraz kilka jej abstrakcji wy$szego poziomu, dzi%ki którym znacznie zmniejsza si% ilo'( wy-
maganego do napisania kodu /ród#owego. Funkcja

jQuery.ajax()

przyjmuje mi%dzy innymi

zbiór ustawie& parametrów wywo#ania, typ zawarto'ci oraz odwo#ania zwrotne. W momencie
wywo#ania funkcji $ danie jest asynchronicznie wykonywane w tle.

url

Adres URL $ dania. Domy'lnym adresem URL jest adres bie$ cej strony.

success

Funkcja, która ma zosta( wywo#ana, gdy $ danie zako&czy si% powodzeniem. Wszystkie
dane zwrócone przez serwer s przekazywane do funkcji jako jej parametr.

contentType

Ustawia nag#ówek

Content-Type

$ dania. Je$eli $ danie zawiera dane, domy'lnym typem

zawarto'ci jest

application/x-www-form-urlencoded

, które sprawdza si% w wi%kszo'ci przy-

padków.

data

Dane, które nale$y przes#a( do serwera. Je$eli nie jest to ci g znaków, jQuery je zseriali-
zuje i zakoduje.

type

Metoda HTTP, której nale$y u$y( do wykonania $ dania:

GET

,

POST

lub

DELETE

. Metod

domy'ln jest

GET

.

dataType

Typ danych, jakiego oczekuje si% od serwera. Biblioteka jQuery wymaga podania typu
danych wynikowych, aby wiedzie(, w jaki sposób je przetwarza( po ich otrzymaniu. Je$eli

dataType

nie zostanie okre'lony, jQuery spróbuje ten typ odgadn ( na podstawie typu

MIME odpowiedzi z serwera. Obs#ugiwane s nast%puj ce warto'ci parametru:

text

Odpowied/ tekstowa, która nie wymaga $adnego dodatkowego przetwarzania.

script

jQuery przyjmie, $e danymi wynikowymi jest kod JavaScript, i odpowiednio te dane
przetworzy.

json

jQuery przyjmie, $e danymi wynikowymi s dane JSON, i przetworzy je przy u$yciu
dok#adnego parsera.

jsonp

Oznacza format JSONP, który zostanie przedstawiony w dalszej cz%'ci ksi $ki.

Jako przyk#ad zdefiniujemy proste $ danie Ajax, które wy'wietli dane zwrócone przez serwer:

jQuery.ajax({
url: "/ajax/endpoint",
type: "GET",
success: function(data) {
alert(data);
}
});

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

*adowanie danych

57

Jednak definiowanie wszystkich opcji jest do'( uci $liwe. Na szcz%'cie jQuery udost%pnia
kilka krótszych rozwi za&. Funkcja

jQuery.get()

pobiera adres URL, opcjonalne dane oraz

wywo#anie zwrotne:

jQuery.get("/ajax/endpoint", function(data){
$(".ajaxResult").text(data);
});

Natomiast aby wys#a( kilka parametrów w ramach $ dania

GET

, mo$na to zrobi( nast%puj co:

jQuery.get("/ajax/endpoint", {foo: "bar"}, function(data){
/* ... */
});

Je$eli spodziewamy si%, $e serwer zwróci dane JSON, trzeba u$y( funkcji

jQuery.getJSON()

,

która automatycznie ustawia opcj%

dataType

$ dania na

"json"

:

jQuery.getJSON("/json/endpoint", function(json){
/* ... */
});

Dost%pna jest analogiczna funkcja

jQuery.post()

, która równie$ przyjmuje adres URL, dane

i wywo#anie zwrotne:

jQuery.post("/users", {first_name: "Alex"}, function(result){
/* K1danie POST Ajax zakoHczy%o si* powodzeniem */
});

Aby skorzysta( z innych metod HTTP, czyli

DELETE

,

HEAD

i

OPTIONS

, trzeba u$y( niskopoziomowej

funkcji

jQuery.ajax()

.

W tym punkcie przedstawiono krótki opis API Ajax biblioteki jQuery. Wi%cej informacji na
ten temat mo$na znale/( w kompletnej dokumentacji dost%pnej na stronie pod adresem
http://api.jquery.com/category/ajax

.

Istotnym ograniczeniem Ajax jest obowi zuj ca w tej technologii zasada to$samego pocho-
dzenia

(ang. same origin policy), która ogranicza mo$liwo'( obs#ugi tylko do $ da& o tej samej

domenie, subdomenie i tym samym porcie, co adres strony, która $ danie wykonuje. Jest po
temu istotna przyczyna: otó$ zawsze, gdy wysy#ane jest $ danie Ajax, wraz z nim wysy#ane
s wszystkie dane cookie domeny. Dla serwera zdalnego jest to znak, $e $ danie pochodzi od
zalogowanego u$ytkownika. Gdyby nie obowi zywa#a zasada to$samego pochodzenia, po-
tencjalny napastnik móg#by pobra( wszystkie wiadomo'ci pocztowe innej osoby z jej skrzynki
Gmail, zmienia( statusy na czyim' profilu Facebooka albo publikowa( wiadomo'ci w czyim'
imieniu na Twitterze — jednym s#owem, by#oby to istotne zagro$enie bezpiecze&stwa.

Jednak zasada to$samego pochodzenia, która jest istotnym elementem systemu bezpiecze&-
stwa w sieci WWW, nak#ada na programistów bardzo niewygodne ograniczenia, poniewa$
odbiera im mo$liwo'( korzystania z w pe#ni bezpiecznych zasobów zdalnych. Inne technologie,
na przyk#ad Adobe Flash i Java, udost%pniaj obej'cia tego problemu w postaci plików z re-
gu#ami dost%pu do innych domen. Do tego towarzystwa do# czy# ostatnio Ajax wraz ze swoim
standardem o nazwie CORS (http://www.w3.org/TR/access-control), wyznaczaj cym zasady wspó#-
u$ytkowania zasobów mi%dzy domenami.

Dzi%ki CORS mo$na wy#ama( si% z zasady to$samego pochodzenia i uzyska( dost%p do au-
toryzowanych, zdalnych serwerów. Specyfikacja standardu CORS zosta#a zaimplementowana
w najwa$niejszych przegl darkach, dlatego je'li tylko nie jest u$ywana przegl darka IE6, nie
powinno by( z tym standardem wi%kszych problemów.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

58

Rozdzia# 3. Modele i dane

Zakres obs#ugi standardu CORS w poszczególnych przegl darkach opisano poni$ej:

"

IE >= 8 (z pewnymi ograniczeniami).

"

Firefox >= 3.

"

Safari: pe#na obs#uga.

"

Chrome: pe#na obs#uga.

"

Opera: brak obs#ugi.

Korzystanie z CORS nie sprawia $adnych problemów. Aby autoryzowa( dost%p do w#asnego
serwera, wystarczy do nag#ówka zwracanych odpowiedzi dodawa( te dwa wiersze:

Access-Control-Allow-Origin: przyklad.com
Access-Control-Request-Method: GET,POST

Powy$szy nag#ówek autoryzuje $ dania

GET

i

POST

do innej domeny wykonywane z domeny

przyklad.com

. Gdy warto'ci jest wi%cej ni$ jedna, nale$y oddzieli( je od siebie przecinkami,

tak samo jak w przypadku metod

GET

,

POST

powy$ej. Aby umo$liwi( dost%p z wi%cej ni$

jednej domeny, wystarczy zawrze( ich list% oddzielon od siebie przecinkami w nag#ówku

Access-Control-Allow-Origin

. Natomiast aby zezwoli( na dost%p z dowolnej domeny, nale$y

w nag#ówku

Origin

wpisa( znak gwiazdki (

*

).

Niektóre przegl darki, na przyk#ad Safari, najpierw wykonuj $ danie

OPTIONS

, aby spraw-

dzi(, czy kolejne $ danie b%dzie dozwolone. Z kolei Firefox prze'le od razu w#a'ciwe $ danie
i dopiero w przypadku braku nag#ówków CORS rzuci wyj tek. W trakcie implementowania
kodu /ród#owego trzeba wzi ( pod uwag% te ró$nice w dzia#aniu serwerów.

Standard CORS pozwala nawet na autoryzowanie $ da& z niestandardowymi nag#ówkami.
S#u$y do tego nag#ówek

Access-Control-Request-Headers

:

Access-Control-Request-Headers: Authorization

Tak skonstruowany nag#ówek oznacza, $e klienty mog dodawa( w#asne nag#ówki do $ da&
Ajax i na przyk#ad podpisywa( $ dania za pomoc OAuth:

var req = new XMLHttpRequest();
req.open("POST", "/endpoint", true);
req.setRequestHeader("Authorization", oauth_signature);

Niestety, mimo $e standard CORS jest obs#ugiwany w Internet Explorerze 8 i jego nowszych wer-
sjach, Microsoft zignorowa# specyfikacj% standardu i grup% robocz (http://lists.w3.org/Archives/
Public/public-webapps/2008AprJun/0168.html

) i utworzy# w#asny obiekt

XDomainRequest

(http://msdn.

microsoft.com/en-us/library/cc288060%28VS.85%29.aspx

), którym w przypadku $ da& mi%dzy

domenami nale$y zast pi( obiekt

XMLHttpRequest

. Obiekt

XDomainRequest

ma interfejs podobny

do interfejsu obiektu

XMLHttpRequest

, jednak zdefiniowano dla niego wiele dodatkowych ograni-

cze& i restrykcji (http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-
limitations-and-workarounds.aspx

). Na przyk#ad obiekt obs#uguje tylko metody

GET

i

POST

, nie s

obs#ugiwane nag#ówki uwierzytelniania ani nag#ówki niestandardowe, a w ko&cu — i to
jest najdziwniejsze — spo'ród typów zawarto'ci obs#ugiwany jest wy# cznie

Content-Type:

text/plain

. Zatem aby skorzysta( z CORS w IE, trzeba — oprócz u$ycia prawid#owych na-

g#ówków

Access-Control

— opracowa( odpowiednie obej'cia dla wspomnianych przed chwil

ogranicze&.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

*adowanie danych

59

JSONP

JSONP (http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp), albo inaczej JSON z wy-
pe#nianiem, to technologia opracowana przed zdefiniowaniem standardu CORS. JSONP sta-
nowi kolejne narz%dzie do pobierania danych ze zdalnych serwerów. Mechanizm dzia#ania
JSONP polega na tym, $e definiowany jest znacznik skryptu, który wskazuje na ko&cówk%
JSONP. Tam w#a'nie zwracane dane s opakowywane w wywo#anie funkcji. Znaczniki skryp-
tów nie podlegaj ograniczeniom zwi zanym z komunikacj mi%dzy domenami, a poza tym
opisywana technika jest obs#ugiwana w#a'ciwie przez ka$d przegl dark%.

Poni$ej przedstawiono znacznik skryptu, który wskazuje na zdalny serwer:

<script src="http://przyklad.com/dane.json"> </script>

Ko&cówka dane.json zwraca obiekt JSON opakowany w wywo#anie funkcji:

jsonCallback({"data": "foo"})

Nast%pnie definiuje si% funkcj% dost%pn globalnie. Gdy tylko skrypt zostanie za#adowany,
nast pi wywo#anie tej funkcji:

window.jsonCallback = function(result){
// Przetwarzanie danych wynikowych
}

Jak wida(, proces jest do'( zawi#y. Na szcz%'cie jQuery udost%pnia o wiele bardziej zwi%z#e
API do niego:

jQuery.getJSON("http://przyklad.com/dane.json?callback=?", function(result){
// Przetwarzanie danych wynikowych
});

Biblioteka jQuery zast pi ostatni znak zapytania w powy$szym adresie URL losow nazw
utworzonej tymczasowej funkcji. Serwer b%dzie musia# natomiast odczytywa( parametr

callback

i u$ywa( go w roli nazwy zwracanej funkcji opakowuj cej.

Bezpiecze-stwo %$da- mi&dzy domenami

Je$eli posiadany serwer jest udost%pniany dla $ da& JSONP z ró$nych domen, trzeba do-
g#%bnie przemy'le( kwesti% jego zabezpieczenia. Zazwyczaj zasada wspó#u$ytkowania zaso-
bów mi%dzy domenami uniemo$liwia potencjalnemu napastnikowi na przyk#ad wywo#anie
API Twittera i pobranie osobistych danych innych u$ytkowników. Wszystko zmienia si% jed-
nak w przypadku zastosowania CORS i JSONP. Podobnie jak w przypadku zwyk#ego $ dania
Ajax, wszystkie cookie sesji s przekazywane w ramach $ dania, co oznacza, $e zalogowanie
do API Twittera ju$ si% dokona#o. Potencjalny napastnik b%dzie wi%c móg# przej ( pe#n
kontrol% nad kontem, a to przes dza spraw% — bezpiecze&stwo wymaga najwy$szej uwagi.

Je$eli zatem nie mo$na z góry ograniczy( zbioru domen, które b%d korzysta( z API i planuje
si% u$y( technologii CORS/JSONP, nale$y zastosowa( si% do nast%puj cych wytycznych:

"

Nie nale$y ujawnia( $adnych poufnych danych, takich jak adresy poczty elektronicznej.

"

Nie mo$na zezwala( na wywo#anie jakichkolwiek akcji (jak na przyk#ad „follow” na
Twitterze).

Aby zapewni( odpowiedni poziom bezpiecze&stwa, mo$na tak$e z góry wyznaczy( okre'lone
domeny, które b%d mog#y korzysta( z API, lub u$y( uwierzytelnienia OAuth.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

60

Rozdzia# 3. Modele i dane

Wype#nienie ORM danymi

Wype#nienie biblioteki ORM odpowiednimi danymi jest bardzo prostym zadaniem. Wystar-
czy pobra( dane z serwera, po czym uaktualni( rekordy modelu. Dodamy zatem funkcj%

populate()

do obiektu

Model

. Funkcja

populate()

b%dzie iterowa( przez kolejne przekazane do

niej warto'ci oraz tworzy( instancje i uaktualnia( obiekty

records

:

Model.extend({
populate: function(values){
// Reset modelu i obiektu records
this.records = {};

for (var i=0, il = values.length; i < il; i++) {
var record = this.init(values[i]);
record.newRecord = false;
this.records[record.id] = record;
}
}
});

Teraz mo$na ju$ u$y( funkcji

Model.populate()

wraz z wynikiem $ dania, które pobiera dane:

jQuery.getJSON("/assets", function(result){
Asset.populate(result);
});

W ten sposób wszystkie dane zwrócone przez serwer stan si% dost%pne w bibliotece ORM.

Przechowywanie danych lokalnie

W przesz#o'ci przechowywanie danych na lokalnym komputerze by#o ogromnym wyzwa-
niem. Jedynym dost%pnym rozwi zaniem by#o wykorzystanie plików cookie oraz modu#ów
rozszerzaj cych, takich jak Adobe Flash. Cookie maj przestarza#e API, nie mog przecho-
wywa( zbyt du$ej ilo'ci danych, a wszystkie znajduj ce si% w nich dane s przesy#ane do
serwera wraz z ka$dym $ daniem, co niepotrzebnie zwi%ksza transfer. Je'li za' chodzi o Flash,
wystarczy powiedzie(, $e najlepiej trzyma( si% z dala od wszystkich modu#ów rozszerzaj cych.

Na szcz%'cie mechanizm przechowywania danych lokalnie zawarto w specyfikacji HTML5
i jest on obs#ugiwany przez wi%kszo'( wspó#czesnych przegl darek. W odró$nieniu od cookies
dane s w tym przypadku przechowywane wy# cznie po stronie klienta i nigdy nie s prze-
sy#ane na serwery. Ilo'( danych, które mo$na w ten sposób przechowywa(, jest tak$e niepo-
równanie wi%ksza, a maksymalny dozwolony wolumen zale$y od przegl darki (oraz jej wersji,
zgodnie z list poni$ej); nigdy jednak wolumen ten nie jest mniejszy ni$ 5 MB na domen%:

"

IE >= 8.

"

Firefox >= 3.5.

"

Safari >= 4.

"

Chrome >= 4.

"

Opera >= 10.6.

Mechanizm przechowywania danych zosta# opisany w specyfikacji Web Storage HTML5
(http://www.w3.org/TR/webstorage) i sk#ada si% z dwóch elementów: przechowywania lokalnie
(ang. local storage) oraz przechowywania w sesji (ang. session storage). Dane przechowywane

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Dodanie mechanizmu przechowywania danych lokalnie do ORM

61

lokalnie zostaj utrzymane równie$ po zamkni%ciu przegl darki, natomiast dane przecho-
wywane w sesji s dost%pne wy# cznie do czasu zamkni%cia okna. Wszystkie dane s prze-
chowywane w kontek'cie ich domeny i udost%pniane wy# cznie tym skryptom, które pocho-
dz z domen stanowi cych /ród#o tych danych.

Aby skorzysta( z mechanizmów przechowywania danych lokalnie i przechowywania danych
w sesji, nale$y u$y( odpowiednio obiektu

localStorage

oraz

sessionStorage

. Odpowiednie API

jest bardzo podobne do w dzia#aniu do mechanizmu ustawiania w#a'ciwo'ci na obiektach
JavaScriptu i, je'li nie liczy( ró$nic w nazwach obydwóch wspomnianych obiektów, jest iden-
tyczne dla obydwóch mechanizmów:

// Ustawienie warto&ci
localStorage["someData"] = "wem";

API WebStorage udost%pnia jeszcze kilka innych funkcji:

// Liczba przechowywanych elementów danych
var itemsStored = localStorage.length;

// Ustawienie danych
localStorage.setItem("someData", "wem");

// Pobranie danych, zwrócenie null, je&li dane s1 nieznane
localStorage.getItem("someData"); //=> "wem";

// Usuni*cie danych, zwrócenie null, je&li dane s1 nieznane
localStorage.removeItem("someData");

// Wyczyszczenie wszystkich elementów danych
localStorage.clear();

Dane s przechowywane w postaci ci gów znaków, dlatego je'li konieczne b%dzie zapisanie
obiektów albo liczb ca#kowitych, trzeba b%dzie samodzielnie dokona( odpowiednich prze-
kszta#ce&. Aby to zrobi( przy u$yciu JSON, nale$y zserializowa( obiekty do postaci JSON
przed ich zapisaniem, natomiast w przypadku odczytywania obiektów — zdeserializowa(
ci gi znaków JSON:

var object = {some: "object"};
// Serializacja i zapisanie obiektu
localStorage.setItem("seriData", JSON.stringify(object));
// Za%adowanie i deserializacja obiektu
var result = JSON.parse(localStorage.getItem("seriData"));

Je$eli wolumen danych przekroczy dozwolony rozmiar (zwykle jest to 5 MB na jeden serwer /ró-
d#owy), w momencie próby zapisania kolejnych danych zwrócony zostanie b# d

QUOTA_EXCEEDED_ERR

.

Dodanie mechanizmu
przechowywania danych lokalnie do ORM

Dodajmy do biblioteki ORM opcj% przechowywania danych na lokalnym komputerze, aby
umo$liwi( utrzymanie rekordów mi%dzy kolejnymi od'wie$eniami strony. Aby skorzysta(
z obiektu localStorage, nale$y zserializowa( rekordy do postaci ci gu znaków JSON. Problem
polega na tym, $e obecnie zserializowane obiekty wygl daj nast%puj co:

var json = JSON.stringify(Asset.init({name: "foo"}));
json //=> "{"parent":{"parent":{"prototype":{}},"records":[]},"name":"foo"}"

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

62

Rozdzia# 3. Modele i dane

Trzeba wi%c pokry( mechanizm serializacji JSON dla naszych modeli. W tym celu najpierw
ustalmy, które w#a'ciwo'ci trzeba zserializowa(. Do obiektu

Model

dodamy tablic%

attributes

,

w której ka$dy z modeli b%dzie wskazywa# odpowiednie atrybuty przeznaczone do serializacji:

Model.extend({
created: function(){
this.records = {};
this.attributes = [];
}
});

Asset.attributes = ["name", "ext"];

Poniewa$ ka$dy model ma odmienne atrybuty, przez co modele nie mog wspó#u$ytkowa(
tej samej tablicy

attributes

, w#a'ciwo'ci tej nie ustawia si% bezpo'rednio na obiekcie

Model

.

Zamiast tego nowa tablica jest tworzona w momencie tworzenia modelu — analogicznie jak
w przypadku obiektu

records

.

Utworzymy teraz funkcj%

attributes()

, która zwróci obiekt dla atrybutów i warto'ci:

Model.include({
attributes: function(){
var result = {};
for(var i in this.parent.attributes) {
var attr = this.parent.attributes[i];
result[attr] = this[attr];
}
result.id = this.id;
return result;
}
});

Dla ka$dego modelu mo$na ju$ zdefiniowa( tablic% atrybutów:

Asset.attributes = ["name", "ext"];

Wówczas funkcja

attributes()

b%dzie zwraca( obiekt z odpowiednimi w#a'ciwo'ciami:

var asset = Asset.init({name: "document", ext: ".txt"});
asset.attributes(); //=> {name: "document", ext: ".txt"};

Aby pokry( funkcj%

JSON.stringify()

, wystarczy wykona( metod%

toJSON()

na instancjach

modeli. Biblioteka JSON wyszuka za pomoc tej funkcji obiekt przeznaczony do zserializo-
wania, zamiast zserializowa( obiekt

records

w jego obecnej postaci:

Model.include({
toJSON: function(){
return(this.attributes());
}
});

Spróbujmy teraz ponownie zserializowa( rekordy. Tym razem wynikowy ci g znaków JSON
b%dzie zawiera# prawid#owe w#a'ciwo'ci:

var json = JSON.stringify(Asset.records);
json //= "{"7B2A9E8D...":"{"name":"document","ext":".txt","id":"7B2A9E8D..."}"}"

Skoro serializacja JSON dzia#a bez zarzutu, dodanie obs#ugi przechowywania danych lokal-
nie do naszego modelu b%dzie trywialne. Do obiektu

Model

dodamy w tym celu dwie funkcje:

saveLocal()

oraz

loadLocal()

. W trakcie zapisywania obiekt

Model.records

zostanie przekszta#-

cony w tablic%, zserializowany i wys#any do

localStorage

:

var Model.LocalStorage = {
saveLocal: function(name){
// Przekszta%cenie records w tablic*
var result = [];

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Przesy#anie nowych rekordów na serwer

63

for (var i in this.records)
result.push(this.records[i])

localStorage[name] = JSON.stringify(result);
},

loadLocal: function(name){
var result = JSON.parse(localStorage[name]);
this.populate(result);
}
};

Asset.extend(Model.LocalStorage);

Zapewne dobrym pomys#em b%dzie odczytywanie rekordów z lokalnego repozytorium
w trakcie #adowania strony i ich zapisywanie, gdy strona b%dzie zamykana. Zostawiam to
jednak jako (wiczenie dla Czytelników.

Przesy#anie nowych rekordów na serwer

Nieco wcze'niej w tej ksi $ce pokazano, jak wykorzystywa( funkcj%

post()

biblioteki jQuery,

aby przesy#a( dane do serwera. Funkcja przyjmuje trzy argumenty: docelowy adres URL,
dane $ dania i wywo#anie zwrotne:

jQuery.post("/users", {first_name: "Alex"}, function(result){
/* K1danie POST Ajax zakoHczy%o sie powodzeniem */
});

Dzi%ki wcze'niejszemu zaimplementowaniu funkcji

attributes()

tworzenie rekordów na ser-

werze jest ju$ proste — wystarczy metod

POST

przes#a( atrybuty rekordu:

jQuery.post("/assets", asset.attributes(), function(result){
/* K1danie POST Ajax zakoHczy%o sie powodzeniem */
});

Aby konsekwentnie trzyma( si% konwencji REST, w momencie tworzenia rekordu nale$y
wykonywa( $ danie HTTP

POST

, za' w chwili zmiany tego rekordu — $ danie HTTP

PUT

.

Dodajmy zatem do instancji

Model

dwie funkcje o nazwach

createRemote()

i

updateRemote()

,

które b%d odpowiada( za wys#anie do serwera $ dania HTTP odpowiedniego rodzaju:

Model.include({
createRemote: function(url, callback){
$.post(url, this.attributes(), callback);
},

updateRemote: function(url, callback){
$.ajax({
url: url,
data: this.attributes(),
success: callback,
type: "PUT"
});
}
});

Teraz, je'li na instancji zasobu

Asset

zostaje wywo#ana funkcja

createRemote()

, atrybuty in-

stancji s przesy#ane do serwera metod

POST

:

// Sposób uJycia:
Asset.init({name: "jason.txt"}).createRemote("/assets");

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

64

Rozdzia# 3. Modele i dane

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

255

Skorowidz

A

Adobe Flash, 116

Ajax, 226
Ajax Crawling, 77
akcje szablonowe, 217

alias $, 221, 227
alias fn, 23

Alman Ben, 44
AMD, Asynchronous Module Definition, 93
analiza

DOM, 140
CSS, 140

wydajno'ci sieci WWW, 156
$ da& sieciowych, 144

anulowanie zdarze&, 101

API, 33

Ajax, 226

biblioteki jQuery, 39, 55, 221
biblioteki Spine, 171

do obs#ugi plików, 97
History, 79, 80
History HTML5, 78

Socket.IO, 119
WebSocket, 119

aplikacja

Less.app, 234
Holla, 15, 120

architektura aplikacji, 18, 47
arkusze stylów Less, 234

asercje, 125
atrybut, 180, 203

data-main, 94

defer, 150
files, 99

multiple, 98

audyt strony internetowej, 155

audytory, 155
automat sko&czony, 74
automatyczna aktualizacja widoku, 88

B

Backbone, 179

aplikacja, 192
delegowanie zdarze&, 184
kolekcje, 181
komunikacja z serwerem, 188
kontrolery, 186
modele, 180
obs#uga historii, 187
wi zanie, 185
widoki, 183

barwa, hue, 236
bezpiecze&stwo, 98, 115
bezpiecze&stwo $ da&, 59
biblioteka

Backbone, 179
Controller, 73
Envjs, 134
gem Ruby-YUI-compressor, 153
Growl, 228
Ichabod, 136
Jammit, 153
JavaScriptMVC, 199
jQuery, 15, 32, 221
jQuery UI, 228
jQuery.tmpl, 83, 86, 195
Less, 231
Less.js, 234
Modernizr, 248
ORM, 60
Prototype, 33
QUnit, 126
Rhino, 90
Selenium, 132
Socket.IO, 118
SpiderMonkey, 90
Spine, 33, 157
Sprocket, 153

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

256

Skorowidz

biblioteka

Sprockets, 95
Super.js, 27
Watir, 131

Vows.js, 135
YUI Compressor, 153

YSlow, 155
Zepto.js, 179

Zombie.js, 134

biblioteki

asercji, 126

#adowania modu#ów, 92
odwzorowa& obiektowo-relacyjnych, 48

pomocnicze, 20
powiadomie&, 228
szablonów, 83

testuj ce, 129
zdarze&, 39

b#%dy aplikacji, 142

C

CDN, Content Delivery Network, 92, 154

cieniowanie, 238
Comet, 113
CommonJS, 90

CORS, 57
CRUD, Create, Read, Update, Delete, 188

CSS, 231

rozszerzenia, 231

CSS3, 232, 235, 250
czas wykonania kodu, 147
czat, 120

czcionki, 246

D

Dangoor Kevin, 90

data wyga'ni%cia zasobu, 151
debugger JavaScriptu, 140, 143

definiowanie cieni, 238
deklarowanie modu#u, 90
delegowanie, 29

delegowanie zdarze&, 40, 72, 168, 184
d#ugotrwa#e po# czenie, long polling, 113

dodawanie

dziedziczenia, 26

funkcji, 23
funkcji prywatnych, 31
kontekstu, 67

metod, 24
przezroczysto'ci, 237

w#a'ciwo'ci, 24
w#a'ciwo'ci instancji, 33
w#a'ciwo'ci klasy, 33

dokumentacja jQuery, 225
dokumentacja LABjs, 96
DOM, 39
domenowy j%zyk skryptowy DSL, 132
dost%p do plików, 97, 99
dost%p do widoków, 70
DRY, Don’t Repeat Yourself, 69
duszki CSS, CSS sprites, 149
dynamiczna wersja strony, 78
dziedziczenie, 26
dziedziczenie klas, 25
dziedziczenie statyczne, 201

E

ECMAScript, 17
eksport przypadków testowych, 133
elegancka degradacja, graceful degradation, 235, 247
element Socket.IO, 119
enkapsulacja us#ug, 207
Envjs, 134
ES5, 30
etykietowanie elementu, 219

F

Firebug, 140
format JSON, 116
formularz form, 108
FSM, Finite State Machine, 74
FUBC, 96
funkcja

$$(), 142
$(), 142
$x(), 142
activate(), 75
add(), 74
addChange(), 87
addClass(), 224
addElement(element, x, y), 101
addEventListener(), 35, 40

listener, 35
type, 35
useCapture, 35

ajax(), 226
App.log(), 142
append(), 223
apply(), 27
assert(), 14, 125
assertEqual(), 14
attributes(), 63, 162
autoLink(), 84

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

257

Backbone.sync(), 188, 190

method, 191
model, 191
options, 191

bind(), 30, 39, 45, 225
call(), 27
change(), 87
clear(), 142
close(), 116
comparator(), 183

confirm(), 37
console.log(), 141, 144
console.profile(), 146

console.profileEnd(), 146
contextFunction(), 67

create(), 50
created(), 159
createRemote(), 63

deactivate(), 75
delegate(), 40, 42

delegateEvents(), 72
destroy(), 48
dir(), 142

document.createElement(), 81
eval(), 91

extend(), 25, 45
fetch(), 189

find(), 52
getData(), 104
getJSON(), 226

history.pushState(), 79
html(), 224

include(), 25, 68
init(), 50, 71
inspect(), 143

jQuery.ajax(), 56, 57
jquery.makeArray(), 29

jQuery.post(), 57
jQuery.proxy(), 29, 226
jQuery.tmpl(), 83

keys(), 143
loadLocal(), 62

Math.random(), 52
module(), 127

Object.create(), 49
populate(), 60
post(), 63

prepend(), 223
preventDefault(), 37

proxy(), 29, 40, 68
publish(), 45
ready(), 39

refresh(), 189
refreshElements(), 72, 168

removeEventListener(), 35

render(), 184
require(), 90, 93
route(), 187

saveLocal(), 62
saveLocation(), 187

send(), 108, 115
setData(), 100

setDragImage(), 101
slice(), 106
stopImmediatePropagation(), 37

stopPropagation(), 37
subscribe(), 45

template(), 175
test(), 127
text(), 225

toggleClass(), 69
toJSON(), 184

trigger(), 41, 161
update(), 53
uploadFile(), 111

validate(), 164, 181
values(), 143

funkcje

anonimowe, 31
konstruktora, 22

obs#ugi szablonów, 84
pomocnicze aplikacji, 84

pomocnicze konsoli, 142
porównuj ce, 130

G

generator identyfikatorów GUID, 52
generowanie obiektu JSON, 55

generowanie widoku, 81, 184
Go, 119
Google Chrome Frame (GCF), 249

gradienty, 239, 251
GUID, Globally Unique Identifier, 52

Gzip, 153

H

hash value, 76, 79

historia przegl darki, 79
HJS, 32

Holla, 15, 120
HTML5, 97

I

Ichabod, 136
identyfikator ID, 52
implementowanie sterownika, 131

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

258

Skorowidz

informacje o pliku, 101, 109
inkapsulacja zasi%gu, 21
inspektory, 138
instalacja Spine, 157
interfejs kana#owy, 119
interoperacyjno'( kodu, 90
iteracje, 84
iterator

each(), 223
map(), 223

J

Jasmine, 129
jasno'(, lightness, 236
JavaScriptMVC, 199

$.Class, 199
$.Controller, 199
$.Model, 199
$.View, 199
kontrolery, 213
metoda bazowa, 201
modele, 203, 205
obs#uga szablonów, 211, 213
tworzenie klasy, 200

jQuery

nextPrev, 204

JSMin, 153
JSON, 207
Juggernaut, 119

K

kana# alfa, 236
kana# RSS, 120
kaskadowe arkusze stylów, 231
klasa

$.Class, 200
$.Controller, 200, 215
$.Model, 207
$.View, 210, 212
active, 41
Backbone.Controllers, 186
Class, 202
Clicky, 201
Controller, 69
foo, 221
nag#ówków, 151
no-js, 248
potomna, 26
selected, 221
Spine.List, 174
WebSockets, 115

kolejno'( elementów, 183
kolekcje, 182
kolory, 236
kompilacja Less, 233, 234
kompresja Gzip, 153
komunikacja z serwerem, 188
konfiguracja JavaScriptMVC, 200

konsola, 141
konstruktor jQuery, 223

konteksty, 28, 134, 160
kontroler, 21, 166, 186, 213

aplikacji, 65
App, 178
Contacts, 175

Sidebar, 173

kontrolka do przesy#ania plików, 98

kontrolki stronicowania

count, 203
limit, 203

offset, 203

kontrolowanie zasi%gu, 30

konwencja REST, 63
kopiowanie, 103

L

LABjs, 96
Less.app, 234
liczba $ da& HTTP, 149

lista dozwolonych domen klientów, 117
lista mechanizmów transportowych, 118

lista zada&, 218
logika prezentacji, 20

*

#adowanie

danych, 54, 55

modu#u, 92
plików na serwer, 107
równoleg#e, 96

synchroniczne modu#ów, 91
szablonów, 85

widoku, 212

#a&cuchy wywo#a&, 227
# czenie modu#ów, 95

M

manipulowanie modelem DOM, 223
maszyna stanów, 45, 74

metoda

alert(), 138

DELETE, 207
GET, 207

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

259

multipart/form-data, 109
POST, 207
PUT, 207
toJSON(), 62

metody pomocnicze, 206
migawki, 147
minifikacja, 95, 152
model, 19

Contact, 173
danych kontaktowych, 173
DOM, 223
elastycznych kontenerów, 245
Paginate, 205

warto'ci domy'lne, 206

Task, 207

modele, 161, 180, 203
modu#, 25

Adobe Flash, 60
application, 92
CommonJS, 92
HJS, 32
maths.js, 91
mod_deflate, 154
nextPrev, 204
Spine.Events, 161
utils, 93
V8 JS, 118
Web Inspector, 136

modu#y, 89
modyfikatory jQuery, 211
MVC, Model View Controller, 18, 85, 180

N

nag#ówek

Expires, 150
Last-Modified, 152
protoko#u HTTP, 114

nagrywanie sesji, 132
narz%dzie

Fetch as Googlebot, 78
Firebug, 140, 155
Firebug Lite, 141
Juggernaut, 119
LABjs, 96
MooTools, 39
Prototype, 39
Pusher, 119
rack-modulr, 95
Selenium IDE, 132
TestSwarm, 137
Web Inspector, 138
YUI, 39

narz%dzie do przesy#ania plików, 98
nas#uch zdarzenia click, 21
nas#uchiwanie zdarze&, 218
nasycenie, saturation, 236
natywna implementacja klas, 22
natywna obs#uga klas, 32
natywny inspektor kodu, 140
nazwy funkcji konstruktorów, 22
negacja selektorów, 242
negocjowanie po# cze& TCP, 114
Node.js, 118

O

obiekt

Asset, 45
Blob, 106
clipboardData, 103
Controller, 68
dataTransfer, 102
elements, 72
event, 36, 37
Events, 72, 74
exports, 68
File

name, 98
size, 98
type, 98

FileList, 98
FileReader, 105
FormData, 108
localStorage, 61
Model, 49
prototypowy, 26
rpc, 116
sessionStorage, 61
User, 48

obiekty wstrzymane, deferred objects, 212
obserwatory zdarze&, 115
obs#uga

IE6, 235
modu#ów, 25
przeci gania, 100
przej'(, 242
szablonów, 211
szablonów HTML, 195
wywo#a& zwrotnych, 25
zdarze&, 161

obszar upuszczania, 111
odpytywanie ci g#e serwera, 113
opakowywanie modu#ów, 94
opcje nag#ówka, 151

max-age, 151
must-revalidate, 151

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

260

Skorowidz

no-store, 151
public, 151

operator

new, 22
not, 242

this, 225
var, 31

ORM, 45, 48, 52

P

pami%( podr%czna, 150

pasek post%pu, 109
platforma programistyczna JS, 199
platforma Rack, 233

plik

application.rb, 233

helpers.js, 84
production.rb, 234
spine.model.local.js, 164

pliki cookie, 60
pliki PSD, 235

polecenie rackup, 95
po# czenia wss, 117
po# czenie zdublowane, 115

pr%dko'( dzia#ania, 121
pr%dko'( generowania stron, 156

proces JuggernautObserver, 120
profilowanie kodu, 146
protokó# WebSocket, 117

prototyp

Function, 31

Object.prototype, 26
prototype, 23

przechowywanie

danych, 60
lokalne, local storage, 60

stanu na kliencie, 65
szablonów, 85

w sesji, session storage, 60

przeci ganie, 100

plików poza przegl dark%, 101

tekstu, 100

przedrostki stylów, 236

przegl darka

Chrome, 123, 235
Firefox, 123, 235

IE, 123, 235
Opera, 123

Safari, 123, 235

przej'cia, 242
przekierowanie

robota, 78
sta#e, 78
tymczasowe, 78

przep#yw zdarze&, 19
przestrze& nazw, 20, 89
przesy#anie plików, 108, 111

przetwarzanie plików, 97
przezroczysto'(, 236

punkt przerwania, 143
Pusher, 119

Q

QUnit, 126

R

Rack, 119

Rack and Rails, 96
regu#y zagnie$d$one, 232

rekomendacje, 155
rekordy, 162, 163
repozytorium GitHub, 15

RequireJS, 93
Resig John, 33

REST, Representational State Transfer, 189, 207
robot, 78
rozmiar $ dania, 114

rozszerzanie klas, 159
rozszerzanie modeli, 205

rozszerzenia jQuery, 227
RPC, Remote Procedure Call, 116
Ruby, 25

S

selektor nth-child, 241

selektory, 221, 241
Selenium IDE, 132
serwer zdarzeniowy, 118

serwis Quirksmode, 36
sie( dostarczania tre'ci, 154

silnik generowania stron WWW, 235
silnik WebKit, 103
sk#adnia stylów CSS3, 254

s#owo kluczowe

class, 23

new, 23
this, 23, 67

Socket.IO, 118

specyfikacja

Ajax Crawling, 78

JavaScript, 30
Web Storage, 60

Spine, 32, 157

aplikacja, 172, 178
delegowanie zdarze&, 168
klasy, 158

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

261

kontrolery, 166
modele, 161
proxied, 167

w#a'ciwo'( elements, 167
zapisywanie, 164
zdarzenia, 161

zdarzenia standardowe, 163

Sprockets, 95

stan aplikacji, 76
stan strony, 65
standard CORS, 58

sterowniki, drivers, 131
stronicowanie, 203

styl

@font-face, 246
border-image, 244

border-radius, 237
box-shadow, 238

box-sizing, 244
hsl, 236
rgb, 236

text-shadow, 239

style gradientów CSS3, 236

style standardowe, 235
subszablony, 212

szablony, 82

EJS, 211
JAML, 211

#adowanie wst%pne, 213
Micro, 211

pakowanie, 213
Tmpl, 211

@

'rodowisko testowe, 126

T

tabela zgodno'ci zdarze&, 36

tablica

asocjacyjna atrybutów, 180

asocjacyjna zdarze&, 184
attributes, 62
nazw atrybutów, 161

nazw funkcji, 167

technologia

AJAX, 55
JSONP, 55, 59
Rails, 120

Ruby, 95

testowanie

kodu, 123
niezale$ne, 134
rozproszone, 137

testy

Jasmine, 131
JavaScript, 131
jednostkowe, 125
QUnit, 128

t#o, 241
tooltip, 215
Tornado, 119
transformacje, 244
Transport C, 92
Transport D, 92
tworzenie

asercji, 130
biblioteki Growl, 228
gniazdka, 115
graficznych interfejsów u$ytkownika, 245
instancji, 22, 158, 200
instancji kontrolera, 216
instancji modelu na serwerze, 208
klas, 22
klasy, 200
kolekcji, 182
kontrolerów, 65, 70, 186
modeli, 180
ORM, 48
rekordów na serwerze, 63
statycznych szablonów, 235
uk#adu, 250
widoków, 81
wid$etów, 219

typ

atrybutów, 209
MIME, 56
zwracanych danych, 105

typy zdarze&, 37

U

ukrywanie zak#adek, 42
upuszczanie, 101
us#uga REST, 207
ustawianie warto'ci, setters, 205
utrzymywanie rekordów, 51

W

W3C, 35
warstwa abstrakcji, 121, 180
warstwa abstrakcji dla zdarzenia, 100
Watir, 131
wczytywanie pliku, 105
wdra$enie aplikacji internetowej, 149
Web Inspector, 138, 145
WebKit, 235

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

262

Skorowidz

WebSockets, 114
Web-sockets-js, 116
weryfikacja poprawno'ci, 164
wiadomo'ci Message, 120
wi zanie, 86

modeli, 87
zdarze&, 216

widok, 20

AppView, 195
TodoView, 195

widoki, 183
wid$et

dymku z porad , 214
listy, 215
nextPrev, 214

witryna Mozilla Developer, 55
wklejanie, 104
w#asne

przyciski przegl darki, 107
wywo#anie zwrotne, 86
zdarzenia, 168
znaczniki skryptów, 85

w#asny protokó#, 116
w#a'ciwo'ci, 24

ORM, 50
zdarze&, 38

w#a'ciwo'( elements, 167
wplatanie danych, 55
wplecenia, 232
wyciekanie pami%ci, 214
wydajno'( aplikacji, 90, 94, 114, 149
wydzielanie biblioteki, 68
wykrywanie WebSockets, 115
wype#nianie kolekcji, 189
wywo#anie zwrotne, 45
wywo#ywanie funkcji, 27
wywo#ywanie metody bazowej, 201
wzorzec

Element, 170
Module, 228
modu#u, 66
MVC, 47, 180
Publish/Subscribe, 43
PubSub, 119, 120
Render, 170

X

XHR, 92
XMLHttpRequest, 108, 226

Y

Yabble, 92

Z

zadanie CRUD

pobieranie, 208
tworzenie, 208
uaktualnianie, 209
usuwanie, 209

zamykanie po# czenia, 116
zarz dzanie

oczekiwaniami, expectation management, 122
zale$no'ciami, 89, 96
zdarzeniami, 39

zasada to$samego pochodzenia, 57
zasi%g klasy, 29
zasi%g kontekstu, 67
zdarzenia

anulowanie, 37
CRUD, 210
delegowanie, 40
globalne, 169
kontrolera, 168
modelu, 163
nas#uchiwanie, 35
przechodz ce w dó#, event capturing, 36
przechodz ce w gór%, event bubbling, 36
typy, 37
w#asne, 41
w#a'ciwo'ci, 38

zdarzenie

beforecopy, 103
beforecut, 103
beforepaste, 104
blur, 36
change, 36, 87
change.tabs, 42
click, 36
copy, 103
cut, 103
dblclick, 36
document.ready, 225, 227
DOMContentLoaded, 39
drag, 100
dragend, 100
dragenter, 100
dragleave, 100
dragover, 100, 102
dragstart, 100
drop, 100, 101
focus, 36
hashchange, 77

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

263

load, 110
mousemove, 36
mouseout, 36
mouseover, 36
onerror, 105
onhashchange, 187
onload, 105
onmessage, 115
onopen, 115
onprogress, 105
paste, 104
popevent, 80
popstate, 80
progress, 110
submit, 36

zmienna self, 225
zmienne globalne, 31

eksport, 66
import, 66

znaczniki ETags, 152

znak

dolara, 221
dwukropka, 101
hash, 221
podkre'lenia, 31
uko'nika, 150
wykrzyknika, 78

Zombie.js, 134

F

$ dania Ajax, 56, 226
$ dania HTTP, 55, 63
$ danie

DELETE, 56
GET, 56, 57
OPTIONS, 58
POST, 56, 63
PUT, 63

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Czytaj dalej...

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ


Wyszukiwarka

Podobne podstrony:
informatyka splatana siec przewodnik po bezpieczenstwie nowoczesnych aplikacji www michal zalewski e
JavaScript Aplikacje WWW jascww 2
JavaScript Aplikacje WWW
JavaScript Aplikacje WWW
JavaScript Aplikacje WWW 2
informatyka javascript mocne strony douglas crockford ebook
informatyka javascript programowanie obiektowe stoyan stefanov ebook
JavaScript Aplikacje WWW jascww
informatyka java ee 6 programowanie aplikacji www krzysztof rychlicki kicior ebook
ARCHITEKTURA Bazodanowych aplikacji WWW, edukacja i nauka, Informatyka
informatyka programowanie aplikacji dla urzadzen mobilnych z systemem windows mobile jacek matulewsk
biznes i ekonomia grywalizacja mechanika gry na stronach www i w aplikacjach mobilnych gabe zicherma
informatyka php nuke tworzenie witryn www douglas paterson ebook
informatyka android flash zaawansowane programowanie aplikacji mobilnych stephen chin ebook
informatyka ajax bezpieczne aplikacje internetowe christopher wells ebook
informatyka javascript wprowadzenie shelley powers ebook
informatyka php i html tworzenie dynamicznych stron www jacek ross ebook
informatyka javascript wzorce stoyan stefanov ebook
informatyka adobe air dla programistow javascript leksykon kieszonkowy mike chambers ebook

więcej podobnych podstron