Linux E X P R E S

Facebook

jQuery (15) – připojování dat k objektům, odložené zpracování

jQuery

Framework jQuery umožňuje připojovat k objektům v DOM prakticky libovolná data. Kromě této oblasti se podíváme také na odložené zpracování.


Proč připojovat data k objektům

Mnohdy je potřeba v souvislosti s objekty DOM pracovat s nějakými dalšími daty. Ty si lze samozřejmě uložit do nějaké globální proměnné, ale to pak znamená, že v globálním jmenném prostoru přibývají identifikátory. Také si lze globálně vytvořit objekt, jehož položky budou data různých objektů DOM.

Ale proč to všechno, když jQuery nabízí elegantnější a jednodušší mechanismus? K objektům DOM lze připojovat data a pak s nimi dále pracovat. Rozhraní má podobu klasického úložiště typu klíč–hodnota.

Data objektů DOM

Nastavování a získávání dat

Je to velmi jednoduché – prostě se na instanci jQuery zavolá metoda, která data připojí:

$('#search-form').data('timeout', 2000);
$('#search-form').data('timeouts', [ 2000, 1000, 800 ]);

První řádek připojí k objektu s daným identifikátorem data s klíčem „timeout“ a jednoduchou číselnou hodnotou. Druhý řádek přiřadí pole hodnot; podobně by se dal použít i objekt. Pokud se již nastavená hodnotu pro určitý klíč nastaví znovu, data se přepíší. Lze nastavit i více dat najednou:

var obj = {
 timeout: 2000,
 msg: 'Vypršel časový limit.'
};

$('#search-form').data(obj); 

Zafunguje to tak, jako kdyby se hodnoty nastavily postupně. Případné dříve nastavené hodnoty se přepíší, ostatní se nově přidají. Lze tedy používat jak již zmíněné rozhraní typu klíč–hodnota, tak i běžný datový objekt, viz dále.

Pokud je v instanci jQuery více objektů DOM, nastaví se data každému z nich jednotlivě, data tedy nejsou sdílena.

Potřebujeme-li nastavenou hodnotu později získat, použije se tatáž metoda:

var to = $('#search-form').data('timeout');

Při zavolání bez parametrů metoda vrátí kompletní objekt:

var obj = $('#search-form').data();

S takto získaným objektem lze dále pracovat, například změnit hodnoty některých položek a znovu ho nastavit (vrácený objekt je kopií dat, není to reference na živý objekt, kde by se změna položek okamžitě projevila).

Je-li v instanci jQuery více objektů DOM, metoda v obou případech vrátí data prvního z nich.

K dispozici je ještě jedno rozhraní pro nastavování a zjišťování dat:

$.data(document.body, 'timeout', 1000);

Metoda se volá přímo na třídě jQuery a místo selektoru se používá instance typu Element. V tomto případě nemůže nastat situace, že by se operace týkala více objektů DOM najednou.

Test existence, smazání dat

Potřebujeme-li otestovat, zda nějaká data u objektu DOM existují, je to snadné:

if ($('#menu').hasData('effect')) {
  …
}

U testu platí totéž jako u jejich získávání, tedy v případě více objektů DOM ve výběru se test týká jen prvního z nich. Obdobně můžeme data také odstranit, pokud už nejsou potřeba:

$('#menu').removeData('effect');
$('#menu').removeData([ 'effect', 'timeout' ]);
$('#menu').removeData();

První příkaz odstraní hodnotu uloženou pod klíčem „effect“ (ze všech objektů DOM, které selektor vybere), druhý hodnoty pro všechny klíče v daném poli, poslední pak odstraní všechno (s určitými výjimkami, viz dále). Také tady je k dispozici i druhé rozhraní, kdy se metoda volá na třídě jQuery.

Atributy HTML5, obsluha událostí

Pozor na to, že jQuery využívá tento mechanismu také pro své vnitřní potřeby. Jednak do připojených dat uloží atributy (data-*) daného elementu, což může někoho překvapit, když si uložené hodnoty vytáhne a uvidí tam „cosi navíc“. Tyto hodnoty navíc nelze odstranit voláním removeData(), takže i pokud se tato metoda zavolá bez parametrů, mohou v objektu zbýt data.

Detekuje-li jQuery, že jsou data v atributu uložena jako validní JSON, zpracuje je a převede na javascriptovou objektovou strukturu. V ostatních případech zůstávají v původní, textové podobě.

Dalším překvapením může být, že si jQuery k objektům připojuje svá data pro obsluhu událostí. Pokud si tedy nastavíte obsluhu například pomocí metody bind() nebo některé ze zkratek (třeba click()), najdete data v objektu vráceném metodou data()zavolanou bez parametrů.



Odložené zpracování

Pokud si vzpomenete na animační frontu z minulého dílu, budete zhruba v obraze, co znamená odložené zpracování. Zkrátka se připraví a (dříve či později) spustí nějaká činnost, která může chvíli trvat. Pomocí front lze zařídit hodně, ale někdy je potřeba ještě víc, například sledovat průběh nějaké operace.

Už poměrně dávno (ve verzi 1.5) proto přibyl do jQuery objekt Deferred. Ten nabízí širokou škálu možností pro odložené zpracování, navíc ho jQuery používá i interně, například pro síťovou komunikaci (metoda ajax() a další).

Příprava a spuštění odloženého zpracování

Příprava odloženého zpracování začíná získáním instance třídy Deferred z tovární metody třídy jQuery:

var d = $.Deferred();

Dále je potřeba nastavit obsluhu událostí. To lze učinit přímo na instanci objektu Deferred, pokud k tomu má ale dojít někde jinde, je lepší použít instanci třídy Promise. Ta poskytuje jen metody k nastavení obsluhy událostí a nikoli ostatní metody objektu Deferred, jejichž zavolání by zasáhlo do probíhajícího zpracování.

var p = d.promise();
p.done(function() {
  alert('Úspěšně hotovo');
}) 
.fail(fuction() {
  alert('Došlo k chybě');
});

Výše uvedený kód nastaví reakce na úspěšné dokončení zpracování a na chybu. Lze nastavit i více obslužných funkcí najednou, stačí místo jedné funkce předat jejich pole. Tímto je základní příprava skončena a zbývá napsat výkonnou funkci, která zajistí vlastní odložené zpracování.

function mywork(d) {
  …
  if (ok) {
    d.resolve();
  } else {
    d.reject();
  }
}

Funkce (může to být samozřejmě i metoda objektu) vykoná svou práci a podle výsledku zavolá na objektu Deferred buď resolve() při úspěchu nebo reject() při chybě. V příkladu je vše bez parametrů, ale lze předávat i parametry.

setTimeout(mywork, 1000);

Jeden z obvyklých způsobů spouštění odloženého zpracování je časovač (viz výše), ale obecně lze používat i jiné cesty (třeba reakci na činnost uživatele). Za běhu lze zvenčí zjišťovat stav zpracování (bude buď „pending“, pokud ještě běží, nebo „resolved“ či „rejected“ při úspěchu, resp. chybě):

alert('Stav zpracování: ' + p.state());

Sledování průběhu zpracování

Tento mechanismus umožňuje kromě jiného i sledovat průběh, například posouvat nějaký ukazatel, zobrazovat čísla apod. Je potřeba nastavit reakci podobně, jako se to dělá pro dokončení procesu:

p.progress(function(val) {
  $('#complete').text(val);
});

Při vlastním zpracování se pak provádí notifikace o jeho průběhu:

for (var i = 1; i <= 100; i++) {
  …
  d.notify(i);
}

V příkladu je zpracování v cyklu, které informuje po každém jeho proběhnutí. Na závěr se samozřejmě zavolá metoda podle výsledku zpracování.

Mechanismus odloženého zpracování umí ještě různé další lahůdky, například řetězení a filtraci. Informace najdete v dokumentaci nebo podrobném tutoriálu.

jQuery UI

To by bylo o základním jQuery zatím vše, i když se k němu budeme ještě vracet. Příští díl seriálu začne novou část, která bude věnována nadstavbě: jQuery UI. Ta je zaměřena vysloveně na uživatelské rozhraní a je zajímavá přinejmenším stejně jako jádro jQuery.

Diskuze (6) Nahoru