JavaScript a zpětné volání mezi okny
Občas dostávám úlohy, které zpočátku vypadají zapeklitě, ale postupem času mi přijdou jednoduché. Nejinak tomu bylo při řešení problému, kdy bylo třeba zajistit zpětné volání rodičovského okna z okna dceřiného. Součást rodičovského okna tvořil formulář, pro vyplňování číselníkových hodnot tohoto formuláře se otevíralo dceřiné okno s číselníkem, ze kterého si při výběru přenesly hodnoty do okna rodičovského.
Pro zvýšení uživatelského komfortu vzniknul požadavek, aby bylo možné při vložení hodnoty
z číselníku nastavit např. formulářové nabídky či provést jinou akci. Celý problém se musel vyřešit tak obecně, aby to nijak neovlivnilo klientské skripty, které číselníky používají, ale tuto funkčnost nepotřebují.
Jak na to
Pokud je potřeba zprostředkovat komunikaci mezi dceřiným a rodičovským oknem tak nemůžeme
začít nikde jinde, než u objektu opener, ve kterém má každé otevřené okno vytvořené voláním window.open(), odkaz na okno rodičovské.
Jako rozhraní mezi oběma okny bude sloužit funkce, nazveme ji například onenumsubmit, která bude volána na rodičovském okně při
ukončení práce s dceřiným oknem.
Funkce onenumsubmit bude volána s každým použitím dceřiného okna, ale budeme muset zajistit ošetření stavu kdy tato funkce nebude existovat. Pro tento účel
se nabízí využití výjimek a chráněného bloku pomocí try, catch nebo testu
na existenci funkce s využitím automatické konverze datových typů v JavaScriptu
Na ukázku si na onenumsubmit navěsíme klientskou funkci, kterou si implementují klientští programátoři. Pro zpestření si ukážeme, jak universálně předat
další argumenty pro naši klientskou funkci a jejich vyzvednutí za pomocí pole arguments.
Komentované řešení
Začneme přípravou klientské funkce, ve které si můžeme implementovat logiku podle vlastní potřeby.
function myListener(){
//logika pracující s rodičovským oknem
}Připravenou funkci myListener pověsíme na onenumsubmit. Funkci
onenumsubmit musíme zároveň přidat objektu window, v dceřiném okně nám pak opener ukazuje na window s funkcí onenumsubmit.
window.onenumsubmit = myListener;Případně
Pro jednoduchost připravíme klientským programátorům co největší komfort. Protože používáme v rámci našich řešení XSL, připravil jsem jednoduchou šablonu, kterou mohou klientští programátoři volat.
window.onenumsubmit = myListener;
.
.
.volání
.
myListenerKlientskou část tedy kód pro rodičovské okno máme připravený, nyní si ukážeme jak volat
onenumsubmit z dceřiného okna. Díky volání onenumsubmit se zavolá i naše funkce myListener. Volání můžeme spojit s uzavřením dceřiného okna(window.close()) nebo události onunload.
opener.onenumsubmit()Bohužel takto jednoduše neošetříme přiklad kdy funkce onenumsubmit nebude
existovat. Můžeme použít zmíněný try, catch nebo test funkce.
try{
opener.onenumsubmit()
}catch(e){
//ignoruj výjimku
}if(opener.onenumsubmit){
//funkce existuje
opener.onenumsubmit();
}Rád bych upozornil, že ignorovat výjimky prázdným catch blokem není dobrá praktika. Výjimka, kterou jsme se rozhodli ignorovat prázdným catch blokem, totiž
nemusí být nutně vyvolána neexistencí funkceonenumsubmit, ale i
chybou v těle klientské funkce pověšené naonenumsubmit, v našem ilustrativním příkladem vmyListener.
Pokud by tento případ nastal, měli bychom horké chvilky při dohledávání chyby neboť ta by byla vždy "spolknuta" bez jakéhokoliv chybového hlášení.
Nakonec jsem si nechal malé zpestření v předávání argumentů do klientské funkce. V JavaScriptu neni možné přetěžovat funkce počtem nebo typem argumentů, na druhou stranu všechny argumenty jsou v kontextu volané funkce k dispozici v poli arguments.Řekněme, že bychom si rádi předali do klientské funkce dvě hodnoty z dceřiného okna.
if(opener.onenumsubmit){
opener.onenumsubmit("fooValue","hooValue");
}function myListener(){
fooValue = arguments[0];
hooValue = arguments[1];
}Samozřejmě by jste si rovnou mohli funkcimyListenernavrhnout s argumenty
v deklaraci(myListener(fooValue, hooValue)), ale polearguments
by se mohlo hodit v případech kdy neznáte počet argumentů. Pro vyzkoušení přidávám odkaz na všeshrnující
příklad.
Související články
- (Dagblog 04.06.2003) JavaScript a sdílení proměnných mezi okny
Související články
Související epizody CZ Podcastu
- #217 · Ivo Lukačovič
O Windy, JavaScriptu a budování firem.
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi a Filemon o novinkách v Javě 6 a webových frameworcích.