Autor | Zpráva | ||
---|---|---|---|
Igor Profil * |
#1 · Zasláno: 2. 9. 2011, 12:41:05
Strávil jsem docela dost času s tím, než jsem přišel na to, jak do anonymní funkce (call-back funkce v rámci příkazu .post()) dostat this, které odkazuje na odkaz. Chci se teď zeptat co si myslíte o tomto řešení, jestli je to dostačující, nebo je to zase jen "humus". Případně, jestli bych to měl ještě nějak vylepšit. Uzávěra mi funguje, ale uvnitř funkce CallBackFnc ještě zůstává nedořešeno $(that).delay(), kdyby někdo věděl jak rozjet ten zbytek, budu vděčný za radu.
<script type="text/javascript" > var callBackFnc = function(result){ that = this; return function(result) { if (result=="Data succesfuly updated.") <!-- this is reply from server to AJAX --> { $(that).next().text("Saved");<!-- that refers on anchor; this is OK, span set! --> $(that).delay(1500).queue( <!-- error --> function() { $(that).next().text("").removeClass("off"); $(that).dequeue(); } ); } } } </script> <body> <textarea id=id cols="1" rows="1" >Some text here</textarea> <a class=save href='localhost' onclick='var myfnc = callBackFnc.call(this);$.post("ax.php?action=post&save=1", { tabName: "basic", rid: $("textarea#id").val(), col:"id", val:$(this).prev().val() }, function (result){ myfnc(result);}, "html");return false;'>Save!</a> <span></span> </body> Jak to funguje: Uvnitř callBackFnc je funkce, která bude vrácena po zavolání už s objektem this, se kterým dále pracuju pod proměnnou that. Výsledkem callBackFnc tedy bude uzávěra. Když kliknu na odkaz, tak se provede příkaz var myfnc = callBackFnc.call(this); čímž se objekt this uloží do uzávěry myfnc pod proměnnou that. Provedu .post(), odešle se požadavek na server, přijde kladná odpověď a spustí se call-back funkce (třetí argument .post). Tam se volá myfnc(result), uvnitř tedy pracuji jak s objektem výsledků, tak s objektem that, který odkazuje na odkaz. Doufám, že jsem to popsal správně. Je to docela složité. |
||
Časová prodleva: 3 dny
|
|||
_es Profil |
#2 · Zasláno: 5. 9. 2011, 09:31:57
Igor:
„that = this;“ Používejte var Vo vnútri kódu JavaScriptu sa robia komentáre buď uzavretím medzi /* a */ alebo uzavretím medzi // a koncom riadka. |
||
Igor Profil |
#3 · Zasláno: 5. 9. 2011, 18:43:24 · Upravil/a: Igor
_es:
Díky za upozornění. Jinak problém s $(that).delay() stále nevyřešen. That je tag a, $(that) je Jquery objekt, element [a.save localhost]. |
||
_es Profil |
#4 · Zasláno: 5. 9. 2011, 20:39:02
Igor:
Skús sa nad tým trochu viac zamyslieť, asi to bude mnohonásobne zložitejšie, než je treba. Vieš, že ovládač udalosti sa dá priradiť aj inak ako cez HTML atribút: element.onclick = funkcia; Respektíve, nejaké vlastné metódy má na to aj jQuery. |
||
Igor Profil |
#5 · Zasláno: 6. 9. 2011, 09:28:15 · Upravil/a: Igor
_es:
> Vieš, že ovládač udalosti sa dá priradiť aj inak ako cez HTML atribút: > > 1 > > element.onclick = funkcia; > > > Respektíve, nejaké vlastné metódy má na to aj jQuery. Jo. Zdá se mi, že se to hodí spíše pro statické přiřazování funkce k události. Ale generuji formulář dynamicky, takže by bylo nepraktické a složité to dělat takto. Zkouším použít setTimeout() a uzávěru přímo z toho odkazu. Jde o to, že tu první uzávěru, která má uložený objekt this/objekt odkazu, musím volat z callback funkce (zobrazí se pak "Saved!"). Ale ten druhý příkaz volat z callbacku nemusím. Takže do a.onclick nastavím setTimeout("resetSpan",1500). Je to jen pokus: HTML: <a onclick='var setSpan = callBackFnc.call(this); var resetSpan = resetClosure.call(this);$.post("ax.php?action=post&save=1", { tabName: "basic", rid: $("textarea#id").val(), col:"e", val:$(this).prev().val() }, function (result){ setSpan(result);}, "html");;setTimeout("resetSpan()",1500);return false;' href="localhost" class="save">Save!</a> PS: Zjistil jsem že Firebug 3.6.21 nesprávně zobrazuje a kopíruje html element a místo <a onclick=''> dosadí uvozovky " ". JS: var resetClosure = function(){ var that = this; console.log(this); return function(that) { console.log(that); $(that).next().text("").removeClass("off"); } } Výsledek se však nedostaví, protože setTimeout() hlásí "resetSpan is not defined". Zkoušel jsem taky resetSpan globálně deklarovat a v onclick atrributu ho pouze nastavit. To pak SetTimeout hlásí, že resetSpan is undefined. |
||
_es Profil |
#6 · Zasláno: 6. 9. 2011, 09:51:19
Igor:
„generuji formulář dynamicky, takže by bylo nepraktické a složité to dělat takto.“ Odpadnú tak však problémy s tým, čomu sa rovná this. Okrem toho, definovať funkciu v takej časti kódu môže byť zradné, pretože to je podobné definovaniu v bloku príkazu with. Ak to aj nepoužiješ, tak je namiesto metódy call a vytvorenia premennej navyše jednoduchšie zavolať tú funkciu s argumentom, ktorý je tiež lokálnou premennou. |
||
Igor Profil |
#7 · Zasláno: 6. 9. 2011, 10:16:43 · Upravil/a: Igor
_es:
Přečetl jsem si zmiňovaný odkaz. Moc jsem to nechápal, až v příspěvku #10 je odkaz s názornou ukázkou, tak už asi chápu. Má tento problém nějaké jméno (abych si udělal poznámku)? „je namiesto metódy call a vytvorenia premennej navyše jednoduchšie zavolať tú funkciu s argumentom, ktorý je tiež lokálnou premennou.“ Kterou funkci máš na mysli? Myslíš tu která je výsledkem přes callBackFnc()? To jsem už dříve zkoušel, že jsem chtěl dostat "that" z attributu oclick="that=this; " |
||
_es Profil |
#8 · Zasláno: 6. 9. 2011, 12:10:42
Igor:
„Kterou funkci máš na mysli? Myslíš tu která je výsledkem přes callBackFnc()?“ Nie, myslím funkciu callBackFnc. Ak ju namiesto cez metódu call zavoláš normálne, callBackFnc(this), tak prvý pomenovaný argument v definícii funkcie je zároveň lokálnou premennou a nepotrebuješ vytvárať premennú that, argument result ti je v tvojom kóde aj tak na nič, lebo pri zavolaní callBackFnc.call(this) bude mať hodnotu undefined. |
||
Igor Profil |
#9 · Zasláno: 6. 9. 2011, 14:15:30 · Upravil/a: Igor
_es:
„argument result ti je v tvojom kóde aj tak na nič, lebo pri zavolaní callBackFnc.call(this) bude mať hodnotu undefined.“ Chceš říct, že ten kód (#1) co používám nemůže fungovat? Ale on funguje. „Ak ju namiesto cez metódu call zavoláš normálne, callBackFnc(this), tak prvý pomenovaný argument v definícii funkcie je zároveň lokálnou premennou a nepotrebuješ vytvárať premennú that“ Chápu tě tak, že mi říkáš, ať nahradím setSpan(result); Právě proto ji volat nemůžu, protože argumentem pro callBackFnc() musí být result. Jedině, že bych volal callBackFnc(result, this) Jenže to by pak var callBackFnc = function(result){ console.log(result); console.log(this); Vracel Object { type="POST", url="ax.php?action=post&save=1", more...} a objekt Window (místo anchor) |
||
_es Profil |
#10 · Zasláno: 6. 9. 2011, 14:32:36
Igor:
„Chceš říct, že ten kód (#1) co používám nemůže fungovat? Ale on funguje.“ On funguje presne tak, ako keby bolo v druhom riadku len: var callBackFnc = function(){ Argument result v tej funkcii vôbec nepoužívaš, skús sa zorientovať v tom, o aké argumenty akej funkcie ide a snažiť sa skôr o to, aby to fungovalo a nie vytvárať nejaké samoúčelné nadbytočné veci. Potrebuješ vôbec z funkcie vracať dynamicky vytváranú funkciu? |
||
Igor Profil |
#11 · Zasláno: 6. 9. 2011, 15:04:11 · Upravil/a: Igor
_es:
„Potrebuješ vôbec z funkcie vracať dynamicky vytváranú funkciu?“ Tu jsem vytvořil, abych tam dostal to this. I když jsem to teď předělal zpět tak, aby se dynamicky nevytvářela ta vnitřní funkce a vynechal zápis that=this, tak to už nefunguje (protože by teď this mělo ukazovat na funkci místo na odkaz). Edit: Když to přepíšu takto: var callBackFnc = function(that, result){ if (result=="Data succesfuly updated.") { console.log($(that)); $(that).next().text("Saved").addClass("on");; } } function (result){ callBackFnc(this, result)} Tak $(that) je objekt [Object { type="POST", url="ax.php?action=post&save=1", more...}] čili nikoliv objekt odkazu. Tak už ti vážně nerozumím jak to myslíš |
||
Igor Profil |
#12 · Zasláno: 6. 9. 2011, 17:57:32 · Upravil/a: Igor
Už se mi to povedlo vyřešit. Předem ale upozorňuji, že to asi není čisté a možná je to hnus. Ale aspoň mi to funguje!
var resetSpan; var resetClosure = function(that){ var saveme = that; return function (that) { $(saveme).next().text("").removeClass("off"); } } Toto je voláno z události a.onclick resetSpan = resetClosure(this); setTimeout("resetSpan()",1500); Takže aspoň, že tak... |
||
_es Profil |
#13 · Zasláno: 6. 9. 2011, 18:45:30 · Upravil/a: _es
Igor:
„var saveme = that;“ Už som ti ten princíp písal, argument funkcie si nazval that , teda that už je lokálna premenná tej funkcie, v princípe taká istá, ako keby bola definovaná cez var, nepotrebuješ ďalšiu premennú.
„return function (that)“ Veď ten ďalší argument that si v tejto (vnorenej) funkcii nikde nepoužil.
Doporučujem si doštudovať základy JS - definície funkcie, argumentov a premenných. „setTimeout("resetSpan()",1500);“ Viď: Nepoužívejte eval, ani jeho obdoby |
||
Igor Profil |
#14 · Zasláno: 6. 9. 2011, 20:37:24
A veď ti vravím, že mi to bez toho nejede...
|
||
_es Profil |
#15 · Zasláno: 6. 9. 2011, 21:18:38 · Upravil/a: _es
Igor:
„mi to bez toho nejede...“ var resetClosure = function(that){ return function() { $(that).next().text("").removeClass("off"); }; }; setTimeout(resetSpan, 1500) <a onclick='var that=this; setTimeout(function(){$(that).next().text("").removeClass("off");}, 1500);'> |
||
Igor Profil |
#16 · Zasláno: 7. 9. 2011, 08:37:16
_es:
Mnohokrát dík za názornou ukázku, určitě to vyzkouším. Ale spíš později, včera jsem to už uzavřel a dělám zas něco jiného. |
||
Časová prodleva: 13 let
|
0