MooTools 1.2 - klasa Chain
03 sierpnia, 2008
Miło mi zakomunikować, że jest to ostatni wpis związany bardziej z zagadnieniami teoretycznymi niż praktycznymi, ale za to dość ważny - jeżeli będziecie chcieli tworzyć zaawansowane animacje złożone z kilku efektów następujących po sobie to klasa Chain bez wątpienia bardzo Wam pomoże. Zresztą przyda się ona w każdym wypadku, gdzie wymagane jest wykonywanie operacji w określonej kolejności.
Zaczynamy podobnie
Tak jak w wypadku klas Events i Options, aby skorzystać z możliwości klasy Chain musimy ją dodać we właściwości Implements:
var Testowa = new Class({ Implements: Chain, // dalszy kod klasy });
Oczywiście można to zrobić też poprzez metodę implement obiektu Class:
Testowa.implement(Chain);
A w odróżnieniu do dwóch poprzednich klas, możemy też używać tej klasy poprzez utworzenie obiektu tej klasy:
var Lancuch = new Chain();
Użycie klasy Chain w konstruktorze
Odwołując się do metody chain, możemy utworzyć łańcuch z funkcji podanych jako argumenty konstruktora:
var Testowa = new Class({ Implements: Chain, initialize: function(){ this.chain.apply(this, arguments); this.callChain(); this.callChain(); this.callChain(); } });
Pamiętamy, że samo this.chain.apply(this, arguments) utworzy jedynie łańcuch, natomiast jego wywołanie następuje dopiero po użyciu metody callChain w odpowiedniej ilości - o metodzie callChain napiszę w dalszej części wpisu - na razie wystarczy nam wiedza, że potrzeba ją wywołać tyle razy ile "ogniw" posiada łańcuch, by w efekcie wywołać wszystkie ogniwa łańcucha po kolei.
Późniejsze wywołania typu:
var test = new Testowa( function(){ alert('Pierwsze ogniwo'); }, function(){ alert('Drugie ogniwo'); }, function(){ alert('Trzecie ogniwo'); } );
Spowodują pokazanie się trzech alertów w odpowiedniej kolejności. Warto jeszcze dodać, że zapis:
this.callChain(); this.callChain(); this.callChain();
Możemy zamienić na bardziej uniwersalny i krótszy zapis:
while(this.$chain.length) this.callChain();
Powyższy kod wykona tyle ogniw łańcucha ile podamy - nie jesteśmy zatem w tym wypadku niczym ograniczeni.
$chain.length odnosi się do długości łańcucha this.$chain - to bardzo ważne by odróżniać this.chain i this.$chain w naszej klasie - pierwsze to metoda, która pozwala dodawać nowe elementy łańcucha, a drugie to tenże łańcuch. Dlaczego pętla while w tym wypadku sprawuje się tak dobrze ? Wyjaśnię to przy okazji omawiania metody callChain.
Dodajemy nowe ogniwa łańcucha
Metoda chain pozwala nam na dołączanie nowych ogniw do naszego łańcucha przechowywanego we właściwości $chain.
Zatem gdybyśmy chcieli by nasz łańcuch alertów miał zawsze charakterystyczne ostatnie ogniwo, musielibyśmy zapisać:
var Testowa = new Class({ Implements: Chain, initialize: function(){ this.chain.apply(this, arguments); this.chain(function(){alert('Ostatnie ogniwo');}); while(this.$chain.length) this.callChain(); } });
Gdy użyjemy poprzednio użytego kodu:
var test = new Testowa( function(){ alert('Pierwsze ogniwo'); }, function(){ alert('Drugie ogniwo'); }, function(){ alert('Trzecie ogniwo'); } );
Otrzymamy cztery alerty - pierwsze, drugie, trzecie i ostatnie ogniwo. Oczywiście metoda chain może pobierać kilka funkcji naraz - zamiast pisać powyższy dość długi kod, możemy umieścić go w środku naszej metody (oczywiście tracimy wtedy dowolność treści trzech pierwszych alertów:
var Testowa = new Class({ Implements: Chain, initialize: function(){ this.chain( function(){ alert('Pierwsze ogniwo'); }, function(){ alert('Drugie ogniwo'); }, function(){ alert('Trzecie ogniwo'); } ); this.chain(function(){alert('Ostatnie ogniwo');}); while(this.$chain.length) this.callChain(); } });
I wtedy pokazanie łańcucha wymaga mniej kodu:
var test = new Testowa();
Warto pamiętać, że klasy oparte na Fx i Request mają zaimplementowaną obsługę klasy Chain - ale więcej o tym powiązaniu dowiecie się podczas opisu tych klas.
Czyścimy łańcuch
Jeżeli będziemy mieli potrzebę wyczyszczenia naszego łańcucha wystarczy zastosować metodę clearChain:
this.clearChain();
Metoda ta nie pobiera żadnych argumentów. Można jej używać w różnych sytuacjach - gdy chcemy w pewnym momencie zacząć tworzyć łańcuch operacji od nowa i nie mamy pewności, że jest on pusty. Może też zajść potrzeba wyczyszczenia łańcucha operacji w trakcie wykonywania jednego z ogniw, jeżeli zajdą odpowiednie warunki itp. itd. Do takich sytuacji najlepiej właśnie użyć tej prostej w użyciu metody klasy Chain.
Prawie jak stos
Przyszła pora na metodę callChain - aby zrozumieć istotę jej działania najlepiej wyobrazić sobie nasz łańcuch jako stos ogniw ułożonych w ustalonej kolejności. Metoda callChain powoduje wykonanie pierwszego ogniwa - tego znajdującego się na samym spodzie, a następnie usuwa je. Po tej operacji drugie ogniwo (o ile istnieje) staje się pierwszym ogniwem - tak możemy wywoływać metodę callChain aż do wykonania wszystkich ogniw. Jeżeli kolejne ogniwo nie istnieje (wykonywane aktualnie ogniwo jest jedynym w łańcuchu) to metoda callChain zwraca wartość false.
Dzięki takiej metodzie działania callChain nasz zapis:
while(this.$chain.length) this.callChain();
Działał poprawnie - po każdym wykonaniu this.callChain() wartość this.$chain.length malała o 1, aż do momentu w którym osiągnęła wartość 0, która jak wiadomo jest uznawana za odpowiednik wartości logicznej false - i to spowodowało zakończenie pętli while w odpowiednim momencie.
Warta uwagi jest jeszcze jedna bardzo ciekawa cecha metody callChain. Otóż może ona przyjmować argumenty wywołania następnej funkcji w łańcuchu - zatem wywołując pierwsze ogniwo łańcucha, możemy określić z jakimi argumentami wywoła się drugie ogniwo. Najlepiej pokaże to przykład, który wyświetli potęgi liczb od 6 do 1:
var Testowa = new Class({ Implements: Chain, initialize: function(){ this.chain( function(){ alert(6*6); }, function(i){ alert(i*i); }, function(i){ alert(i*i); }, function(i){ alert(i*i); }, function(i){ alert(i*i); }, function(i){ alert(i*i); }, ); while(this.$chain.length) this.callChain(this.$chain.length); } }); var test = new Testowa();
Wraz ze zmniejszającą się wartością długości łańcucha operacji, otrzymujemy coraz mniejsze wartości potęg liczb, które są przekazywane jako argument metody callChain.
Podsumowanie
I tak oto zakończyliśmy część kursu poświęconą programowaniu obiektowemu w MooTools 1.2 oraz większy blok - części teoretycznej kursu. W następnych częściach zajmiemy się klasą Element, która pozwoli nam na manipulacje wyglądem strony i pozwoli tworzyć interaktywne przykłady - oczywiście wiedza zdobyta do tej pory będzie nam często przydatna :)
Komentarze do wpisu "MooTools 1.2 - klasa Chain":
1.
ewel napisał(a):
05 sierpnia 2008, 18:05:29
a może udałoby Ci sie jakos opisac roznice miedzy MooTools 1.1 a 1.2? mysle ze osoby ktore uzywaly 1, w tym ja chetnie by poczytaly ;)
2.
Dziudek napisał(a):
05 sierpnia 2008, 18:36:19
@ewel – niczego nie obiecuję, ale może jak starczy mi zdrowia to pomiędzy Core i More opublikowałbym kilka wpisów o tych różnicach – czyli Rdzeń frameworka, Obiekty natywne itd. – różnice w poszczególnych sekcjach ;)
Dodaj komentarz: