Sytuację taką mamy np. w trakcie oprogramowywania obsługi zdarzenia
onSuccess
obiektu Ajax.Request
w bibliotece Prototype.Np. tak jak to jest w poniższym przykładzie.
var handlerFunc = function(t) {
alert(t.responseText);
}
var errFunc = function(t) {
alert('Error ' + t.status + ' -- ' + t.statusText);
}
var handlerFunc = function(t) {
var xmlDoc = t.responseXML.documentElement;
//Handle data.
}
new Ajax.Request('/foo/bar', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc, onFailure:errFunc});
[powyższy przykład za http://wiki.script.aculo.us/scriptaculous/show/Ajax.Request]
Czasem jednak chcielibyśmy by do funkcji
handlerFunc()
przekazany został jeszcze jakiś nasz parametr i żeby to przekazanie wyglądało np. tak:
new Ajax.Request('/foo/bar', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc(index), onFailure:errFunc});
Okazuje się, że można to zrobić banalnie prosto ;-)
Przekazanie
handlerFunc(index)
jako callbacka spowoduje, że zostanie podjęta próba wywołania takiej funkcji:
handlerFunc(index)(data);
Wystarczy więc by funkcja
handlerFunc(index)
zwróciła odpowiednią funkcję przyjmującą argument data :-)
function handlerFunc(index) {
return function(data) {
var innerIndex=index;
alert(innerIndex+" "+data.responseText);
}
}
Co ciekawe, gdy użyjemy takiego kodu:
new Ajax.Request('/foo/bar', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc(1), onFailure:errFunc});
new Ajax.Request('/foo/bar2', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc(2), onFailure:errFunc});
To funkcja dla pierwszego requesta otrzyma parametr 1, a dla drugiego 2 :-)
Czyż JavaScript nie jest fajny? :-)
Podobne postybeta
Ajax - Prototype
overload vs varargs
Moja własna akcja w Google Home ;-)
Data binding w Polymerze jest oszukany ;-)
I jak "po bożemu" zrobić updatowanie widoku na podstawie danych z sieci w Androidzie?
Tak, ładny trick.
OdpowiedzUsuńTo pachnie rachunkiem funkcyjnym. W lambda rachunku (pewnie trochę "abuse of ntation" tu będzie, dawno się tym nie bawiłem), gdy mielibyśmy:
handlerFunc = \lambda index data. f(index, data)
moglibyśmy zdefiniować:
function = handlerFunc(index)
czyli function to funkcja polegająca na ustaleniu pierwszego argumentu w handlerFunc.
W porządnym języku funkcyjnym (jak Lisp czy Haskell) dałoby się to zapisać w ten lub podobny sposób, w JavaScript jesteś niestety zmuszony definiować to jako funkcję zwracającą funkcję wprost.
Ale to nie zmienia faktu, że to ładne i ociera sie niebanalną informatykę mimo ze problemik który rozwiązujesz jest bardzo "praktyczny".