Zaawansowane programowanie
w nurcie .NET Framework 3.5.
Microsoft .NET Development Series
Autor: Adam Calderon, Joel Rumerman
Tumaczenie: Mikoaj Szczepaniak
ISBN: 978-83-246-2089-0
Tytu oryginau: Advanced ASP.NET
AJAX Server Controls For .NET Framework 3.5
Format: 168x237, stron: 584
Poznaj najlepsze techniki implementowania wasnych kontrolek
serwera frameworka ASP.NET
Jak skonstruowa niezalene od przegldarek skrypty JavaScript?
Jak zbudowa wasne, niestandardowe usugi aplikacji?
Jak zarzdza relacjami komponentw z elementami modelu DOM?
Kontrolki serwera pozwalaj umieszcza dane dotyczce wygldu przegldarki
i funkcjonalnoci serwera w spjnych obiektach wielokrotnego uytku. Mona je
stosowa nie tylko na wielu stronach tej samej aplikacji szkieletu ASP.NET, ale take
w wielu rnych aplikacjach tego frameworka. Oferuje on mnstwo gotowych, zarwno
wyjtkowo prostych, jak i zoonych kontrolek serwera. Co wicej z jego pomoc
mona rwnie tworzy wasne kontrolki, posiadajce funkcjonalnoci, ktrych
nie zaimplementowano w kontrolkach ju istniejcych. Jak wykorzysta ten potencja
ASP.NET?
Ksika ASP.NET AJAX Server Controls. Zaawansowane programowanie w nurcie
.NET Framework 3.5 zawiera szczegowe wyjanienia i instrukcje, jak korzysta
z frameworka ASP.NET AJAX w procesie tworzenia kontrolek serwera, obejmujcych
funkcjonalno frameworka AJAX. Dziki temu podrcznikowi poznasz wewntrzne
mechanizmy i moliwoci rozszerzania frameworka ASP.NET AJAX. Nauczysz si
konstruowa interaktywne kontrolki przy uyciu elementw zestawu narzdzi AJAX
Control Toolkit oraz budowa wasne, niestandardowe usugi aplikacji.
Programowanie w jzyku JavaScript
Obsuga bdw
acuchy, zmienne i argumenty funkcji
Programowanie biblioteki Microsoft AJAX Library
Dziedziczenie i implementacja interfejsu
Typy wyliczeniowe
Kontrolki
Obiekt Sys. Application
Dodawanie funkcji klienckich do kontrolek serwera
Lokalizacja we frameworku ASP.NET AJAX
Wytwarzanie kontrolek w rodowisku czciowej komunikacji zwrotnej
Usugi aplikacji
Architektura strony klienckiej i architektura serwera
Nie ograniczaj si twrz i dodawaj wasne funkcjonalnoci AJAX do kontrolek serwera!
Spis treci
Sowo wstpne
13
Przedmowa
15
Podzikowania
23
O autorach
27
KOD KLIENTA
31
32
32
32
34
acuchy
Obiekty
Zmienne i argumenty funkcji
Obsuga bdw
Opnianie wykonywania kodu za pomoc limitw i przedziaw czasowych
35
36
43
51
56
64
65
71
Podsumowanie
75
77
78
Wartoci logiczne
Daty i liczby
78
79
Spis treci
acuchy
Tablice
79
80
85
85
92
96
101
111
111
117
118
123
128
Zarzdzanie zasigiem
Delegacje
Wywoania zwrotne
133
134
135
Podsumowanie
137
II
KONTROLKI
Komponenty
Definicja komponentw
141
141
142
Typ Sys.Component
Definiowanie nowych komponentw
Tworzenie komponentw
Podsumowanie wiedzy o komponentach
144
148
153
168
Kontrolki
Nowe pojcia
Definiowanie nowej kontrolki
Tworzenie kontrolki
Podsumowanie wiedzy o kontrolkach
168
170
172
174
175
Zachowania
Definiowanie zachowania
Tworzenie zachowania
Podsumowanie wiedzy o zachowaniach
175
177
178
183
Podsumowanie
183
Spis treci
4
Obiekt Sys.Application
Informacje podstawowe
Tworzenie obiektu Sys.Application
Informacje o typie
Informacje o metodach
7
185
185
185
187
188
Meneder komponentw
Dodawanie komponentu
Odnajdywanie komponentu
Usuwanie komponentu
Uzyskiwanie komponentw
190
191
194
197
198
Procedura inicjalizacji
Proces tworzenia komponentw
Zdarzenie load
198
202
211
Procedura zwalniania
Metoda Sys.Application.dispose
215
216
Podsumowanie
218
219
220
220
225
228
230
231
231
254
254
256
257
Podsumowanie
261
Spis treci
6
263
263
265
269
274
283
284
287
Podsumowanie
320
Wytwarzanie kontrolek
w rodowisku czciowej komunikacji zwrotnej
Dziaanie kontrolki UpdatePanel
Wpyw czciowej komunikacji zwrotnej na komponenty klienckie
321
322
327
332
340
343
357
357
363
365
365
366
Podsumowanie
368
III
KOMUNIKACJA
371
372
374
375
385
386
391
398
398
411
Spis treci
Klasa WebRequest
Komponenty rdzenia dania sieciowego
Podsumowanie
Usugi aplikacji
Usugi czonkostwa, rl i profilw uytkownikw frameworku ASP.NET 2.0
Uwierzytelnianie formularzy
ASP.NET 2.0 Provider Model
Narzdzie Web Site Administration Tool
Czonkostwo
Role
Profile
9
412
417
419
421
421
422
425
427
427
432
438
441
441
446
448
451
454
463
467
Podsumowanie
468
IV
10
471
471
472
472
473
473
473
473
474
Architektura serwera
Atrybuty
Klasy bazowe dla kontrolek rozszerzajcych i kontrolek skryptowych
Klasy projektowe
475
476
480
485
10
Spis treci
11
488
489
490
Animacje
Struktura i rodzaje animacji
Architektura klienta
Architektura serwera
490
490
492
496
Podsumowanie
500
502
506
508
510
511
511
511
512
518
518
522
Podsumowanie
528
DODATKI
A
531
531
531
535
539
Spis treci
C
11
543
543
544
544
546
548
548
553
553
555
555
556
557
558
Skorowidz
559
3
Komponenty
Definicja komponentw
Komponentem jest kady obiekt, ktrego typ kliencki dziedziczy po typie Sys.Component.
Wspomniany typ bazowy Sys.Component jest bardzo wany, poniewa wanie za jego
pomoc bdziemy rozszerza ten framework o nowe komponenty. Tworzenie nowych
komponentw z wykorzystaniem tego typu jest o tyle uzasadnione, e wanie typ
Sys.Component ma kilka specyficznych cech, ktrych nie oferuje aden inny typ biblioteki
Microsoft AJAX Library.
Po pierwsze, komponenty s projektowane z myl o zapenianiu luki dzielcej oprogramowanie klientw i serwerw. Za porednictwem obiektw serwera nazywanych deskryptorami skryptw (ang. script descriptors) moemy wymusza na frameworku ASP.NET
AJAX automatyczne generowanie kodu JavaScriptu odpowiedzialnego za tworzenie egzemplarzy naszych typw komponentw. W ten sposb moemy wiza mechanizmy
oprogramowania klienckiego z kontrolkami naszego serwera WWW bez koniecznoci
umieszczania jakichkolwiek skryptw jzyka JavaScript w klasach tych kontrolek.
142
Rozdzia 3. Komponenty
Definicja komponentw
143
144
Rozdzia 3. Komponenty
TABELA 3.1. Rnice pomidzy komponentami, kontrolkami i zachowaniami
Typ obiektu
Moliwo zwizkw
Moliwo zwizkw
wikszej liczby tego rodzaju
z elementem DOM
obiektw z elementem DOM
Brak moliwoci
(komponent nie moe
by bezporednio
zwizany z elementem
DOM)
Brak moliwoci
(komponent nie moe by
bezporednio zwizany
z elementem DOM)
Kontrolka
Musi by
zwizany z jakim
elementem
modelu DOM.
Nie, pojedynczy
element DOM moe
by zwizany z tylko
jedn kontrolk.
Zachowanie Musi by
zwizany z jakim
elementem
modelu DOM.
Tak, pojedynczy
element DOM moe
by zwizany z jedn
lub wieloma
zachowaniami.
Typ Sys.Component
Sys.Component jest typem bazowym dla wszystkich komponentw i jako taki oferuje zdecydowan wikszo ich elementw funkcjonalnoci. Typ Sys.Component nie dziedziczy po adnym
innym typie, ale implementuje trzy interfejsy: Sys.IDisposable, Sys.INotifyPropertyChanged
oraz Sys.INotifyDisposing. Wszystkie te interfejsy krtko opisano w tabeli 3.2.
Typ Sys.Component
RYSUNEK 3.2. Proces decyzyjny dla wyboru komponentu, kontrolki lub zachowania
TABELA 3.2. Interfejsy implementowane przez typ Sys.Component
Interfejs
Zadanie
Metody
Sys.INotifyPropertyChanged
Sys.INotifyDisposing
Implementuje zdarzenie
zwalniania komponentu.
add_disposing
remove_disposing
Sys.IDisposable
Reprezentuje obiekt
przeznaczony
do zwolnienia.
dispose
145
146
Rozdzia 3. Komponenty
TABELA 3.3. Skadowe typu Sys.Component
Nazwa skadowej
Zadanie
Typ
_id
string
_idSet
boolean
boolean
inicjalizacji.
_updating
boolean
_events
Sys.Event
HandlerList
Oprcz implementowania metod wymaganych przez trzy interfejsy wymienione w tabeli 3.2, klasa Sys.Component udostpnia kilka metod dodatkowych, ktre umoliwiaj
nam operowanie na jej wewntrznych skadowych. W tabeli 3.4 szczegowo opisano zarwno te metody dodatkowe, jak i metody wymagane przez wspomniane trzy interfejsy.
Opis
Skadnia
beginUpdate
comp.beginUpdate();
endUpdate
comp.endUpdate();
updated
Implementacja pusta.
comp.updated();
get_isUpdating
comp.get_isUpdating();
initialize
comp.initialize();
get_initialized
Typ Sys.Component
TABELA 3.4. Metody klasy Sys.Component cig dalszy
Nazwa metody
Opis
Skadnia
dispose
comp.dispose();
Wykonuje metody obsugujce
zdarzenie disposing. Usuwa
waciwo _events z danego
komponentu i anuluje jego rejestracj
w obiekcie Sys.Application.
get_events
comp.get_events();
get_id
comp.get_id();
set_id
comp.set_id(id);
add_disposing
comp.add_disposing
(handler);
remove_disposing
comp.remove_disposing
(handler);
add_propertyChan
ged
comp.add_propertyChanged
(handler);
remove_propertyC
hanged
comp.remove_property
Changed
(handler);
raisePropertyCha
nged
Wykonuje zarejestrowane
metody obsugujce zdarzenie
propertyChanged, przekazujc na
ich wejciu (w formie argumentw
zdarzenia) nazw zmodyfikowanej
waciwoci.
comp.raisePropertyChanged
(propertyName);
147
148
Rozdzia 3. Komponenty
Komponent ErrorHandler
Aby zademonstrowa technik definiowania nowych komponentw, utworzymy nowy,
wasny komponent obsugi bdw. Komponent ErrorHandler bdzie odpowiada za publikowanie obsugiwanych i nieobsugiwanych bdw z wykorzystaniem specjalnej usugi
danych o bdach.
Szkielet
Na pocztek utworzymy szkielet naszego nowego komponentu (patrz listing 3.1).
Typ Sys.Component
Inicjalizacja i niszczenie komponentu
Nasz szkieletow definicj naley jeszcze uzupeni o implementacje metod initialize
i dispose.
W metodzie initialize konstruujemy nasz komponent. Proces konstruowania komponentu obejmuje takie kroki jak dodanie metod obsugujcych zdarzenia do elementw
modelu DOM, doczenie nowego elementu DOM do drzewa i wszystkie inne operacje
wymagane przez konkretny typ komponentw.
W metodzie dispose powinnimy umieci kod odpowiedzialny za zwalnianie naszego
komponentu. Zwalnianie komponentu moe obejmowa odczenie zdarze od elementu
modelu DOM, zniszczenie ewentualnych utworzonych elementw DOM lub zwolnienie
wszelkich innych zasobw utworzonych przez nasz komponent.
149
150
Rozdzia 3. Komponenty
},
dispose: function ErrorHandler$dispose() {
window.onerror = null;
ErrorHandler.callBaseMethod(this, 'dispose');
},
_unhandledError: function(msg, url, lineNumber) {
try {
var stackTrace = StackTrace.createStackTrace(arguments.callee);
ErrorDataService.PublishError
(stackTrace, msg, url, lineNumber);
}
catch (e) { }
}
}
ErrorHandler.registerClass('ErrorHandler', Sys.Component);
Jak wida na listingu 3.2, wykorzystalimy w naszym kodzie kilka interesujcych zabiegw. Po pierwsze, w metodzie initialize utworzono delegacj wskazujc na metod
_unhandledError i skojarzono t delegacj ze zdarzeniem error obiektu window (przypisujc j zdarzeniu onerror).
Typ Sys.Component
151
152
Rozdzia 3. Komponenty
}
},
}
ErrorHandler.registerClass('ErrorHandler', Sys.Component) ;
ErrorEventArgs = function(stackTrace, message, url, lineNumber) {
ErrorEventArgs.initializeBase(this);
this._message = message;
this._stackTrace = stackTrace;
this._url = url;
this._lineNumber = lineNumber;
}
ErrorEventArgs.registerClass("ErrorEventArgs", Sys.EventArgs);
get_disableErrorPublication: function() {
return this._disableErrorPublication;
},
set_disableErrorPublication: function(value) {
if (!this.get_updating()) {
this.raisePropertyChanged("disableErrorPublication");
}
this._disableErrorPublication = value;
},
Typ Sys.Component
_unhandledError: function(msg, url, lineNumber) {
try {
var stackTrace = StackTrace.createStackTrace(arguments.callee);
if (!this._disableErrorPublication) {
ErrorDataService.PublishError
(stackTrace, msg, url, lineNumber);
}
var args =
new ErrorEventArgs(stackTrace, msg, url, lineNumber);
this._raiseUnhandledErrorOccured(args);
}
catch (e) { }
},
}
ErrorHandler.registerClass('ErrorHandler', Sys.Component);
Ostatnia zmiana czyni z naszego typu przydatny komponent, ktry mona z powodzeniem wykorzystywa do wysyania na serwer informacji o bdach wystpujcych po stronie klienta i tym samym powiadamiania programistw o ewentualnych problemach.
Tworzenie komponentw
Na podstawie materiau zaprezentowanego w tym rozdziale do tego momentu mona by
pomyle, e tworzenie nowych komponentw polega na konstruowaniu ich obiektw
i przypisywaniu ich odpowiednim zmiennym (patrz listing 3.5).
153
154
Rozdzia 3. Komponenty
Dziaanie metody Sys.Component.create, ktra jest dostpna take za porednictwem
zmiennej globalnej $create, nie ogranicza si tylko do tworzenia nowego egzemplarza
okrelonego typu. Oprcz tworzenia nowego egzemplarza wskazanego typu metoda
Sys.Component.create rejestruje ten egzemplarz w obiekcie Sys.Application jako komponent zarzdzany, po czym automatycznie wywouje metody beginUpdate, endUpdate,
updating i initialize tego komponentu. Wszystkie te dziaania s podejmowane automatycznie w zalenoci od parametrw uytych w jej wywoaniu. Co wicej, metoda $create
moe przypisywa wartoci pocztkowe waciwoci, dodawa metody obsugujce zdarzenia, przypisywa inne komponenty w formie referencji i wiza z danym komponentem element modelu DOM. I wreszcie metoda $create zwraca wskanik do nowo utworzonego egzemplarza. Jak wida, metoda $create robi duo wicej ni tylko tworzenie
nowego egzemplarza naszego typu.
Typ Sys.Component
Aby zademonstrowa sposb uycia metody $create, przeanalizujemy szereg jej wywoa, zmieniajc parametry przekazywane na wejciu tej metody.
type
155
156
Rozdzia 3. Komponenty
W przedstawionym przykadzie pierwszym dziaaniem metody Sys.Component.create
jest sprawdzenie, czy za porednictwem parametru type przekazano obiekt (w tym przypadku ErrorHandler) typu Type, ktry dziedziczy po klasie Sys.Component. Po sprawdzeniu
tego parametru metoda Sys.Component.create tworzy nowy egzemplarz typu ErrorHandler
i przypisuje go pewnej zmiennej lokalnej.
Typ Sys.Component
ponenty z ustawionymi identyfikatorami s automatycznie dodawane do zbioru komponentw zarzdzanych obiektu Sys.Application. Mona to zmieni, rcznie ustawiajc
identyfikator komponentu i dodajc go do listy komponentw zarzdzanych obiektu
Sys.Application (patrz listing 3.8).
157
158
Rozdzia 3. Komponenty
Warto te pamita, e identyfikatory komponentw zarzdzanych przez obiekt
Sys.Application musz by unikatowe. Gdybymy sprbowali doda do zbioru kompo-
nentw zarzdzanych przez ten obiekt dwa komponenty z tym samym identyfikatorem
(niezalenie od tego, czy zrobilibymy to za porednictwem wyraenia $create, czy rcznie wywoujc metod addComponent), otrzymalibymy bd.
properties
Typ Sys.Component
W kolejnym kroku metoda $create przypisuje przekazane wartoci waciwociom
komponentu. Waciwoci i ich wartoci s przekazywane na wejciu tej metody z wykorzystaniem skadni acuch-obiekt (wyrnionej pogrubieniem na listingu 3.10). Zamiast
korzysta ze wspomnianej skadni, mona by uy przedstawionego na listingu 3.11 kodu
tworzcego obiekt, jednak wanie skadnia acuch-obiekt jest w tej sytuacji krtsza i bardziej
czytelna.
Niezalenie od stosowanej skadni nasz kod wyraa denie do ustawienia dwch waciwoci: id oraz disableErrorPublication.
Aby ustawienie tych waciwoci byo moliwe, metoda $create deleguje sterowanie
do innej metody, nazwanej Sys$Component_setProperties. Ta globalna metoda dostpna
w ramach biblioteki Microsoft AJAX Library zostaa stworzona wanie z myl o ustawianiu
waciwoci komponentw. Metoda Sys$Component_setProperties otrzymuje na wejciu
dwa parametry: obiekt target i obiekt properties.
W ramach tej metody kada z naszych waciwoci expando doczona do parametru
properties jest odczytywana i przetwarzana wedug zbioru cile okrelonych regu.
Pierwsza regua okrela, czy dla danej waciwoci istnieje metoda zwracajca jej warto. Nazw tej metody okrela si, poprzedzajc nazw samej waciwoci (w tym przypadku id) przedrostkiem get_. W naszym przykadzie metoda get_id istnieje w klasie
bazowej Sys.Component, zatem warunek tej reguy jest speniony.
Po stwierdzeniu istnienia metody zwracajcej metoda Sys$Component_setProperties
przystpuje do poszukiwania metody ustawiajcej. Nazwa tej metody powinna si skada
z nazwy samej waciwoci poprzedzonej przedrostkiem set_. Ponownie okazuje si, e
odpowiednia metoda (w tym przypadku set_id) istnieje w klasie bazowej Sys.Component.
Po stwierdzeniu istnienia metody ustawiajcej metoda Sys$Component_setProperties
wywouje j, przekazujc na jej wejciu warto biecej waciwoci. W prezentowanym
przykadzie metoda ustawiajca otrzymuje warto ApplicationErrorHandler.
Opisywany proces jest powtarzany a do momentu skutecznego zastosowania wszystkich waciwoci danego komponentu lub wystpienia jakiego bdu (zwizanego na
przykad z brakiem metody zwracajcej, niewaciw liczb parametrw obsugiwanych
przez metod ustawiajc lub wieloma innymi moliwymi problemami). W naszym przykadzie waciwo disableErrorPublication jest inicjalizowana z wartoci true.
159
160
Rozdzia 3. Komponenty
set_disableErrorPublication: function(value) {
if (!this.get_updating()) {
this.raisePropertyChanged
("disableErrorPublication");
}
this._disableErrorPublication = value;
},
W powyszym przykadzie kodu rdowego przed wygenerowaniem zdarzenia propertyChangedupewniamy si, e dany komponent nie jest aktualizowany. Sprawdzenie flagi _updating jest nieporwnanie mniej kosztowne
ni przechodzenie przez cay proces generowania zdarzenia.
Ostrzeenie: Przedstawiony kod ma wycznie charakter testowy. Przed jego
uyciem powinnimy dokadnie sprawdzi, czy w naszym przypadku zdarzenie propertyChanged rzeczywicie nie powinno by generowane w czasie,
gdy dany komponent jest aktualizowany.
Typ Sys.Component
161
162
Rozdzia 3. Komponenty
var newComponent =
$create(
MyComplexComponent,
{
id: "MyNewComplexComponent",
city: "Sanok",
areaCodes: [619, 858, 760],
someExpandoProperty: "Moja warto waciwoci expando",
subComponent:
{
id: "ApplicationErrorHandler",
disableErrorPublication: "true"
},
myObject: { lastName: "Nowak" }
},
null,
null,
null);
1. Ustawianie wartoci, dla ktrej nie istnieje metoda zwracajca lub ustawiajca.
Ten scenariusz zilustrowano na przykadzie ustawiania waciwoci city
i someExpandoProperty. Tego rodzaju waciwoci mona ustawia, poniewa stanowi istniejce pola swojego obiektu. Gdyby nie istniay, wyraenie setProperties by ich nie dodao.
2. Doczanie elementw do tablicy.
Drugi zaawansowany scenariusz zilustrowano na przykadzie waciwoci
areaCodes. W tym przypadku zdefiniowano now tablic zoon z trzech
elementw (619, 858 i 760) i przypisano j waciwoci areaCodes. Dodawanie elementw do istniejcej tablicy wymaga metody zwracajcej, ale
nie wymaga metody ustawiajcej warto tej waciwoci. W razie istnienia
metody ustawiajcej istnieje moliwo jej uycia zamiast kodu metody
zwracajcej wwczas to kod metody ustawiajcej bdzie odpowiada
za doczenie elementw do tablicy. Warto te pamita o koniecznoci
uprzedniego utworzenia egzemplarza danej tablicy. Jeli okae si, e dana
zmienna wskazuje na null lub undefined, zostanie wygenerowany bd.
3. Ustawianie waciwoci podkomponentu.
Trzeci zaawansowany scenariusz przedstawiono na przykadzie waciwoci subComponent. W tym przypadku zdefiniowano podobiekt zawierajcy
waciwoci id oraz disableErrorPublication, ktre zdefiniowano wczeniej w ramach komponentu ErrorHandler. Kiedy metoda setProperties
odkrywa te waciwoci, uzyskuje dostp do podkomponentu, po czym
rekurencyjnie wywouje metod setProperties, stosujc ten podkomponent w roli parametru target oraz podobiekt zawierajcy te waciwoci
w roli parametru properties. Tego rodzaju wywoania rekurencyjne mog
by wykorzystywane na dowolnej liczbie poziomw (jeli ustawiono parametr properties w odpowiedni sposb).
Typ Sys.Component
Rwnie dobrze moglibymy tutaj zdefiniowa metod zwracajc i otrzyma ten sam efekt, gdybymy jednak dodatkowo zdefiniowali metod
ustawiajc, proces ustawiania waciwoci podkomponentu nie dziaaby
zgodnie z naszymi oczekiwaniami.
Metoda setProperties wywoywana rekurencyjnie z wykorzystaniem
komponentu w roli parametru target sama wywouje metod beginUpdate
tego komponentu przed wejciem w ptl forin i metod endUpdate po
opuszczeniu tej ptli. Warto o tym pamita, jeli w naszym kodzie korzystamy z metody get_updating.
4. Ustawianie waciwoci zwykego obiektu JavaScriptu.
Czwarty, ostatni zaawansowany scenariusz przedstawiono na przykadzie
waciwoci myObject. Waciwo myObject definiuje prosty obiekt zawierajcy waciwo lastName, ktra reprezentuje warto "Nowak". Kiedy
metoda setProperties odkrywa t waciwo, stosuje rekurencyjne wywoanie metody setProperties, aby zastosowa t now waciwo dla
skadowej myObject. Tym razem zamiast przekazywa komponent za porednictwem parametru target, przekazujemy w roli tego parametru
waciwo myObject, a obiekt nowej waciwoci jest przekazywany za
porednictwem waciwoci properties.
Jak wida, parametr properties metody $create moe z powodzeniem obsugiwa kilka zaawansowanych scenariuszy. Jeli bdziesz o tej moliwoci pamita, by moe znajdziesz dla tych rozwiza zastosowania w swoim kodzie.
163
164
Rozdzia 3. Komponenty
events
Typ Sys.Component
Predefiniowanie metod obsugujcych zdarzenia umoliwia ich wielokrotne wykorzystywanie take w innych komponentach lub wywoywanie proceduralne.
Co wicej, gdybymy chcieli obsugiwa zdarzenie za pomoc metody zawartej w naszym
komponencie (zamiast jak w kodzie z listingu 3.13 korzysta z funkcji globalnej),
powinnimy wykona dodatkowy krok polegajcy na utworzeniu delegacji obejmujcej nasz
metod obsugujc, aby kontekst wskazywa na odpowiedni komponent (patrz listing 3.14).
165
166
Rozdzia 3. Komponenty
We fragmencie kodu metody initialize typu MyOtherComponent wyrnionym pogrubieniem utworzylimy egzemplarz komponentu ErrorHandler. Metod obsugujc przypisywan do zdarzenia unhandledErrorOccurred umieszczamy w delegacji, aby umoliwi
wykonywanie metody _unhandledErrorOccurred z wykorzystaniem waciwego kontekstu.
Typ Sys.Component
// tworzy drugi komponent i przypisuje go waciwoci nazwanej
// subComponent i nalecej do pierwszego komponentu
$create(
MyComponent,
{
id: "MySecondComponent"
},
null,
{
subComponent:"MyFirstComponent"
},
null
);
references
167
168
Rozdzia 3. Komponenty
Kontrolki
Kontrolka jest specjalnym rodzajem komponentu bezporednio zwizanym z elementem
modelu DOM. Pojedynczy element DOM moe by zwizany z tylko jedn kontrolk,
a wspomniana kontrolka musi by zwizana tylko z tym konkretnym elementem.
Poniewa z pojedynczym elementem DOM mona zwiza tylko jedn kontrolk,
w praktyce moliwe zastosowania tego rodzaju komponentw ograniczaj si do sytuacji,
w ktrych chcemy dysponowa pen kontrol nad tym elementem modelu DOM. W sytuacji,
gdy nie jestemy pewni swoich oczekiwa odnonie danego elementu DOM, powinnimy
raczej uy zachowania, po czym w razie koniecznoci zastpi je kontrolk. W praktyce
przechodzenie od kontrolek do zachowa (i odwrotnie) nie jest zbyt trudne i nie wymaga
zbyt wielu zmian w kodzie rdowym.
Kontrolki
Poniewa kontrolka jest bezporednio zwizana z elementem modelu DOM, zawiera
metody stworzone specjalnie z myl o uzyskiwaniu dostpu i wykonywaniu operacji na
skojarzonym z ni elementem DOM. W tabeli 3.5 szczegowo omwiono metody kontrolki odpowiedzialne za dostp i modyfikacje powizanego elementu DOM.
Opis
Skadnia
set_id
get_id
return ctrl.get_id();
get_visible
return ctrl.get_visible();
Sys.UI.DOMElement.getVisible
Wywouje metod
Sys.UI.DomElement.setVisible,
ctrl.set_visible
(visibility);
return ctrl.get_visibility
Mode();
get_element
ctrl.set_visibilityMode(
Sys.UI.VisibilityMode
);
return ctrl.get_element();
169
170
Rozdzia 3. Komponenty
TABELA 3.5. Metody klasy Sys.UI.Control cig dalszy
Nazwa metody
Opis
Skadnia
addCssClass
Wywouje metod
ctrl.addCssClass
(cssClassName)
Sys.UI.DomElement.addCssClass,
Wywouje metod
Sys.UI.DomElement.removeCssClass,
ctrl.removeCssClass
(cssClassName);
Wywouje metod
Sys.UI.DomElement.toggleCssClass,
ctrl.toggleCssClass
(cssClassName);
ctrl.dispose();
Nowe pojcia
Oprcz metod, ktre uzyskuj dostp do elementu DOM skojarzonego z dan kontrolk
i operuj na tym elemencie, twrcy klasy Sys.UI.Control wprowadzili dwa nowe pojcia:
rodzic kontrolki (ang. controls parent) i znana z frameworku ASP.NET propagacja zdarze
(ang. event bubbling).
Rodzic kontrolki
Waciwo parent kontrolki zawiera wskanik do innej kontrolki. Warto tej waciwoci jest wyznaczana na dwa sposoby. Jeli waciwo parent ustawiono wprost za pomoc
metody set_parent, warto przekazana za porednictwem parametru tej metody jest
rodzicem danej kontrolki. Jeli rodzica nie okrelono wprost, w jego poszukiwaniu jest
wykorzystywany wskanik parentNode elementu DOM a do odnalezienia elementu skojarzonego z jak kontrolk wanie ta kontrolka jest traktowana jako rodzic naszej
kontrolki.
Metody stworzone z myl o operowaniu na wskaniku do rodzica kontrolki opisano
w tabeli 3.6.
Kontrolki
TABELA 3.6. Metody typu Sys.UI.Control zwizane z rodzicem kontrolki
Nazwa metody
Opis
Skadnia
get_parent
var parent =
ctrl.get_parent();
set_parent
ctrl.set_parent(otherCtrl);
Propagacja zdarze
Propagacja zdarze jest technik polegajc na przekazywaniu zdarze w gr hierarchii
za porednictwem wskanika do rodzica i tym samym umoliwianiu kontrolkom
rodzicw obsugi tych zdarze.
Mechanizm propagowania zdarze zaimplementowany w bibliotece Microsoft AJAX
Library przypomina technik propagowania zdarze z wykorzystaniem kontrolek ASP.NET.
Kontrolka rozpoczyna ten proces, wywoujc metod raiseBubbleEvent i przekazujc na
jej wejciu rdo i argumenty zdarzenia. W ciele metody raiseBubbleEvent jest uzyskiwany rodzic danej kontrolki za porednictwem doczonej do niej metody get_parent, po
czym nastpuje wywoanie metody onBubbleEvent dla tego rodzica. Domylna implementacja metody onBubbleEvent klasy Sys.UI.Control zwraca warto false, oznaczajc,
e dana kontrolka nie obsuya tego zdarzenia i e proces propagacji powinien trwa dalej
(zdarzenie powinno by przekazywane w gr hierarchii).
Jeli dana kontrolka jest zainteresowana obsug tak propagowanego zdarzenia, moe
to zrobi, przykrywajc domyln implementacj metody onBubbleEvent. W przykrytej
metodzie naley okreli, czy proces propagowania zdarzenia powinien by kontynuowany,
czy zatrzymany na poziomie tej kontrolki. Jeli propagacja zdarzenia zatrzymuje si na
rodzicu danej kontrolki, metoda onBubbleEvent zwraca warto true. Jeli jednak dane zdarzenie ma by propagowane dalej, w gr drzewa rodzicw kontrolek, metoda onBubbleEvent
zwraca warto false.
Metody stworzone z myl o technice propagowania zdarze szczegowo opisano
w tabeli 3.7.
171
172
Rozdzia 3. Komponenty
TABELA 3.7. Metody typu Sys.UI.Control zwizane z propagowaniem zdarze
Nazwa metody
Opis
Skadnia
onBubbleEvent
Metoda onBubbleEvent
jest automatycznie
wywoywana
przez metod
raiseBubbleEvent.
raiseBubbleEvent
ctrl.raiseBubbleEv
ent(source, args);
Kontrolki
_keyDownHandler: function(e) {
return ((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode == 8));
}
};
NumberOnlyTextBox.registerClass("NumberOnlyTextBox", Sys.UI.Control);
Jak wida na listingu 3.16, istniej dwie wane rnice dzielce kontrolk NumberOnlyTextBox
od zadeklarowanego wczeniej komponentu ErrorHandler.
Po pierwsze, funkcj klasy bazowej naszej kontrolki NumberOnlyTextBox peni typ
Sys.UI.Control, nie jak wczeniej typ Sys.Component.
Po drugie, konstruktor naszego nowego typu otrzymuje parametr element i przekazuje go
do konstruktora swojej klasy bazowej za porednictwem metody initializeBase. Parametr
element reprezentuje element modelu DOM, ktry ma zosta skojarzony z dan kontrolk.
W odpowiedzi na przekazanie wspomnianego elementu na wejciu konstruktora klasy
Sys.UI.Control s podejmowane trzy dziaania. Po pierwsze, tak przekazany element
DOM jest weryfikowany pod ktem ewentualnego zwizku z inn kontrolk. Jeli okae
si, e taki zwizek istnieje, konstruktor klasy Sys.UI.Control generuje bd i cay proces
tworzenia kontrolki koczy si niepowodzeniem. W przeciwnym razie konstruktor przystpuje do drugiego kroku, polegajcego na przypisaniu tego elementu DOM wewntrznej
skadowej _element. I wreszcie kontrolka sama jest przypisywana temu elementowi modelu
DOM z wykorzystaniem waciwoci expando nazwanej control. Gdybymy utworzyli
referencj do element zwizanego z nasz kontrolk, moglibymy uzyska dostp do zwizanej z nim kontrolki za pomoc nastpujcego wywoania:
$get("TextBox1").control;
LISTING 3.17. Tworzenie egzemplarza typu NumberOnlyTextBox z wykorzystaniem sowa kluczowego new
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Control Testing!</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="SM1" runat="server" />
// dla uproszczenia pominito definicj typu NumberOnlyTextBox
<asp:TextBox ID="txtBox1" runat="server" Width="150px" />
<script type="text/javascript">
var numberOnlyTextBox =
173
174
Rozdzia 3. Komponenty
new NumberOnlyTextBox($get("txtBox1"));
// wywietla txtBox1
alert ("Identyfikator elementu zwizanego z kontrolk numberOnlyTextBox: " +
numberOnlyTextBox.get_element().id);
// wywietla txtBox1
alert ("Identyfikator elementu zwizanego z kontrolk numberOnlyTextBox: " +
$get("txtBox1").control.get_id());
// generuje bd JavaScriptu, poniewa dana kontrolka
// jest ju zwizana z polem txtBox1
var numberOnlyTextBox2 =
new NumberOnlyTextBox ($get("txtBox1"));
</script>
</form>
</body>
</html>
Tworzenie kontrolki
Na listingu 3.17 do utworzenia nowego egzemplarza naszego typu NumberOnlyTextBox
wykorzystalimy sowo kluczowe new. Z podrozdziau powiconego naszemu komponentowi wiemy ju, e metoda $create wykonuje cay pakiet zada i nie ogranicza si
tylko do utworzenia nowego egzemplarza wskazanego typu, a poniewa nasz nowy typ dziedziczy po klasie Sys.UI.Control, ktra z kolei dziedziczy po klasie Sys.Component, moemy
uy wyraenia $create w taki sam sposb jak w przypadku komponentu ErrorHandler.
Zamiast traci czas na ponowne omawianie metody $create, ograniczymy si tylko do
analizy zastosowa parametru element, poniewa tylko w jego przypadku mamy do czynienia z istotnymi rnicami. Podstaw naszych analiz bdzie kod z listingu 3.17, ktry
zmodyfikujemy przez zastosowanie metody $create. Kod powstay w wyniku tych zmian
wprowadzono na listingu 3.18.
Zachowania
<script type="text/javascript">
$create(
NumberOnlyTextBox,
null,
null,
null,
$get("txtBox1")
);
</script>
</form>
</body>
</html>
Zachowania
Zachowanie to kolejny specjalny rodzaj komponentu zwizany z elementami modelu DOM.
Podobnie jak kontrolki, zachowania musz by skojarzone z elementami DOM. Okazuje
si jednak, e w inaczej ni w przypadku kontrolek, pojedynczy element DOM moe by
zwizany z wicej ni jednym zachowaniem.
175
176
Rozdzia 3. Komponenty
W wymiarze praktycznym zachowania definiuj oczekiwany sposb zachowywania si
elementu DOM. Moemy na przykad zdecydowa, e dany element DOM powinien by
zwijany do pojedynczego wiersza, pywa na stronie bd wypenia ca dostpn przestrze na ekranie. Wszystkie te zachowania moemy doczy do elementu modelu DOM
wanie za pomoc egzemplarzy typw zachowa.
Aby uatwi nam definiowanie nowych typw zachowa i korzystanie z egzemplarzy
tych typw, typ bazowy Sys.Behavior definiuje kilka dodatkowych metod, uzupeniajcych
zbir metod oferowanych przez jego typ bazowy Sys.Component. Metody klasy Sys.Behavior
szczegowo omwiono w tabeli 3.8.
Opis
Skadnia
get_element
return behavior.
Zwraca element modelu dom
zwizany z danym zachowaniem. get_element();
get_name
set_name
behavior.set_name
("HiddenElm");
initialize
behavior.initialize();
Zachowania
TABELA 3.8. Metody klasy Sys.UI.Behavior cig dalszy
Nazwa metody
Opis
Skadnia
dispose
get_id
return behavior.
Zwraca warto waciwoci id
get_id();
danego komponentu (jeli t
warto ustawiono). Jeli warto
tej waciwoci nie zostaa
ustawiona, metoda get_id zwraca
identyfikator elementu DOM
powizanego z tym zachowaniem
i nazw samego zachowania.
Sys.UI.Behavior.
getBehaviorsByType
Sys.UI.Behavior.
getBehaviorByName
return Sys.UI.Behavior.
Zwraca zachowanie doczone
do wskazanego elementu modelu getBehaviorByName
(element, behaviorName)
DOM (jeli takie zachowania
istniej).
Sys.UI.Behavior.
getBehaviors
return Sys.UI.Behavior.
Zwraca kopi zachowa
getBehaviors(element);
doczonych do wskazanego
elementu DOM. Jeli okrelony
element modelu DOM nie jest
zwizany z adnymi zachowaniami,
metoda getBehaviors zwraca
tablic pust.
return Sys.UI.Behavior.
getBehaviorsByType
(element, typeName)
Definiowanie zachowania
Podobnie jak podczas definiowania nowych komponentw i nowych kontrolek, definiujc
nowe zachowania posugujemy si modelem prototypowym omwionym w rozdziale 2.
Zamiast tworzy od podstaw nowy przykad, odpowiednio zmodyfikujemy przedstawiony
w poprzednim podrozdziale kod definiujcy kontrolk NumberOnlyTextBox. Na listingu 3.19
przedstawiono kod niezbdny do zdefiniowania zachowania NumberOnlyTextBox.
177
178
Rozdzia 3. Komponenty
LISTING 3.19. Definiowanie typu zachowania
/// <reference name="MicrosoftAjax.js"/>
NumberOnlyTextBox = function(element) {
NumberOnlyTextBox.initializeBase(this, [element]);
this._keyDownDelegate = null;
};
NumberOnlyTextBox.prototype = {
initialize: function() {
NumberOnlyTextBox.callBaseMethod(this,'initialize');
this._keyDownDelegate =
Function.createDelegate(this, this._keyDownHandler);
$addHandler(this.get_element(), "keydown", this._keyDownDelegate);
},
dispose: function() {
$removeHandler
(this.get_element(), "keydown", this._keyDownDelegate);
this._keyDownDelegate = null;
NumberOnlyTextBox.callBaseMethod(this, 'dispose');
},
_keyDownHandler: function(e) {
return ((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode == 8));
}
};
NumberOnlyTextBox.registerClass("NumberOnlyTextBox", Sys.UI.Behavior);
Jak wida, kod definiujcy nasze zachowanie NumberOnlyTextBox niemal niczym nie
rni si od kodu definiujcego wczeniej tak samo nazwan kontrolk. Rnice sprowadzaj si do rezygnacji z typu bazowego Sys.UI.Control na rzecz typu Sys.UI.Behavior.
Podobnie jak konstruktor klasy Sys.UI.Control, konstruktor typu Sys.UI.Behavior
otrzymuje na wejciu parametr reprezentujcy element modelu DOM. W ciele tego konstruktora warto wspomnianego parametru jest przypisywana wewntrznej skadowej
_element, co jest rwnoznaczne ze skojarzeniem odpowiedniego elementu DOM z tworzonym zachowaniem. Nastpnie nasze zachowanie jest dodawane do waciwoci expando nazwanej _behaviors. Waciwo expando _behaviors pod pewnymi wzgldami
przypomina waciwo control stosowan dla kontrolek, ale ma posta tablicy, ktra
moe reprezentowa wicej ni jedno zachowanie zwizane z danym elementem DOM.
Tworzenie zachowania
Z podrozdziaw powiconych komponentom i kontrolkom wiemy, e najlepszym sposobem
konstruowania nowych egzemplarzy typw dziedziczcych po klasie Sys.Component jest
korzystanie z metody $create nie inaczej jest w przypadku zachowa.
Zachowania
W praktyce proces tworzenia zachowania przebiega dokadnie tak samo jak proces
tworzenia kontrolki, zatem kod przedstawiony ju na listingu 3.18 w zupenoci wystarczy
jako przykad tego rozwizania.
Okazuje si jednak, e inaczej ni w przypadku kontrolek, podczas tworzenia zachowa
mog wystpowa dwa powane problemy cile zwizane z unikatowoci zachowa.
179
180
Rozdzia 3. Komponenty
$get("txtBox1")
);
</script>
</form>
</body>
</html>
Poniewa w przedstawionym przykadzie nie ustawilimy wprost nazw ani identyfikatorw tworzonych zachowa, waciwoci id obu tych zachowa bd miay warto txtBox1$NumberOnlyTextBox. Automatycznie generowany identyfikator zachowania skada
si z identyfikatora powizanego elementu DOM (w tym przypadku txtBox1), symbolu $
oraz nazwy samego zachowania, ktra w razie braku nazwy okrelonej wprost jest zastpowana nazw typu zachowania (bez ewentualnych przestrzeni nazw).
Zachowania
$create(
NumberOnlyTextBox,
{id: "Behavior2" },
null,
null,
$get("txtBox1")
);
</script>
Drugi powany problem zwizany z tworzeniem zachowa moe wystpowa w sytuacji, gdy doczamy wiele egzemplarzy tego samego zachowania do jednego elementu
modelu DOM i gdy nazwy tych zachowa nie zostay wprost ustawione. Poniewa automatycznie generowane nazwy egzemplarzy tego samego zachowania bd takie same (na
przykad NumberOnlyTextBox), nie bdziemy mogli ich odnale za porednictwem metody
Sys.UI.getBehaviorByName.
Doczanie wielu egzemplarzy tego samego zachowania do jednego elementu modelu
DOM zdarza si do rzadko, ale nie mona takiej sytuacji wykluczy. Na listingu 3.22
przedstawiono kod ilustrujcy moliwo odnajdywania tylko jednego z zachowa typu
NumberOnlyTextBox skojarzonych z naszym polem tekstowym.
181
182
Rozdzia 3. Komponenty
$get("txtBox1")
);
var beh = Sys.UI.Behavior.getBehaviorByName
($get("txtBox1"), " NumberOnlyTextBox ");
alert (beh.get_name());
var behaviorsAssignedToDom =
Sys.UI.Behavior.getBehaviors($get("txtBox1"));
var behaviors = '';
for (var i=0; i<behaviorsAssignedToDom.length; i++) {
behaviors += behaviorsAssignedToDom[i].get_name() + " ";
}
// wywietla NumberOnlyTextBox NumberOnlyTextBox, poniewa
// zdefiniowano dwa tak samo nazwane zachowania
alert (behaviors);
</script>
</form>
</body>
</html>
Podsumowanie
$create(
NumberOnlyTextBox,
{id: "Behavior2",
name: "Behavior2"},
null,
null,
$get("txtBox1")
);
</script>
Podsumowanie
W tym rozdziale omwiono komponenty, kontrolki i zachowania. Przyjrzelimy si typowi bazowemu komponentw pod ktem jego popularnych obiektw oraz sposobom rozszerzania tego typu przez kontrolki i zachowania, czyli wyspecjalizowane komponenty
zawierajce referencje do elementw modelu DOM. Omwilimy te techniki samodzielnego konstruowania egzemplarzy wszystkich trzech typw oraz sposoby realizacji tych
zada z wykorzystaniem funkcji $create.
W nastpnym rozdziale skoncentrujemy si na obiekcie Sys.Application, ktry peni
funkcj menedera wszystkich komponentw, kontrolek i zachowa. Po omwieniu wspomnianego obiektu przystpimy do analizy technik czenia elementw biblioteki Microsoft
AJAX Library z kodem frameworku ASP.NET AJAX stosowanym po stronie serwera
(w tym technik tworzenia komponentw, kontrolek i zachowa za porednictwem kodu
.NET). I wreszcie, aby ostatecznie wyczerpa temat komponentw, kontrolek i zachowa,
zajmiemy si tematem ich lokalizowania i sposobami reagowania na ich umieszczanie
w kontrolce UpdatePanel.
183