Autor Zpráva
Igor
Profil *
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é.
_es
Profil
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
_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
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
_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(&quot;ax.php?action=post&amp;save=1&quot;, { tabName: &quot;basic&quot;, rid: $(&quot;textarea#id&quot;).val(), col:&quot;e&quot;, val:$(this).prev().val() }, function (result){ setSpan(result);}, &quot;html&quot;);;setTimeout(&quot;resetSpan()&quot;,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
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
_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; "
do té funkce s call-backem a nepovedlo se
_es
Profil
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
_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);
(uvnitř call-back anonymní funkce, druhý arg. .post())
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
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
_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
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
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
A veď ti vravím, že mi to bez toho nejede...
_es
Profil
Igor:
mi to bez toho nejede...
var resetClosure = function(that){ 
     return function()  
      { 
      $(that).next().text("").removeClass("off"); 
      }; 
  };
setTimeout(resetSpan, 1500)
Možno chceš toto:
<a onclick='var that=this; setTimeout(function(){$(that).next().text("").removeClass("off");}, 1500);'>
Igor
Profil
_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.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0