Jag har ett litet problem med min kundvagn. Jag använder AJAX via prototype.js. Det handlar om att en funktion körs innan en annan funktion har hunnit räkna klart.
function calc(){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
manageCart();
// Den här koden vill jag köra när jag är säker på att uträkningen ovan är klar
doSomething();
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError});
}
function calc(){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
manageCart();
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError, onComplete: doSomething});
}
Jag hittade precis dom där callback-möjligheterna och onComplete var ju helt rätt!
Problemet är att jag inte alltid vill anropa doSomething(). Det är bara när jag kör funktionen calc()...
function calc(myFunc){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
manageCart("myId", myFunc);
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id, myFunc){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError, onComplete: myFunc});
}
...
calc(doSomething);
calc(doSomethingElse);
Jag hänger inte riktigt med.
Måste det inte finns en funktion som heter myFunc() någonstans?
Sedan vill jag ju köra funtionen doSomething() inne i funktionen calc(). Nu ligger den utanför men det kanske skall vara så? Dessutom är egentligen inte doSomething ett anrop till en function så som det ser ut i mitt exempel utan några rader vanlig kod. (Men det kan ju skrivas om till en kod om så skulle vara)
MyFunc är alltså en funktionspekare och tanken var att du skickar in en referens till den funktion du vill skall köras i OnComplete.
Så här kan du också göra:
function calc(){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
// functionToRunOnComplete är namnet på den funkion du vill skall köras när anropet är klart
manageCart("myId", functionToRunOnComplete);
}
function functionToRunOnComplete()
{
// ...
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id, func){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError, onComplete: func});
}
Då förstår jag. :) Och nu funkar det ganska bra men finns det något sätt att skicka med argument in till funktionen functionToRunOnComplete() i samband med att jag anropar manageCart()?
Om jag kör manageCart(id, functionToRunOnComplete(id)); så slutar varukorgen att fungera.
Problemet med det är att functionToRunOnComplete inte körs direkt utan du vill i stället "spara" argumentet (id) till senare exekvering (när onComplete körs). Och när den körs - någonstans i Updater - ser det ut så här: onComplete(), vilket egentligen innebär functionToRunOnComplete(). Så när din funktion körs får den inga argument.
Varifrån kommer id-variabeln och kan du inte lägga den direkt i functionToRunOnComplete?
Functionen calc() körs i samband med att man ändrar antalet varor i sin korg (via onclick=""). Då skickar jag med id för att kunna veta vilken vara som skall ökas/minskas. id behöver skickas vidare till både manageCart() och functionToRunOnComplete().
function calc(id){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
// functionToRunOnComplete är namnet på den funkion du vill skall köras när anropet är klart
manageCart("myId", function(){ functionToRunOnComplete(id) });
}
function functionToRunOnComplete(id)
{
// use id...
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id, func){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError, onComplete: func});
}
är det samma id som ska till manageCart som ska till functionToRunOnComplete behöver man inte göra det så komplicerat:
function calc(id){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
// functionToRunOnComplete är namnet på den funkion du vill skall köras när anropet är klart
manageCart(id, functionToRunOnComplete);
}
function functionToRunOnComplete(id)
{
// use id...
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id, func){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError, onComplete: func(id)});
}
ett tredje alternativ är att skicka ett till argument till mangeCart:
function calc(id){
// Detta är ett anrop till en JS-function som håller redan på kundvagnen (AJAX)
// functionToRunOnComplete är namnet på den funkion du vill skall köras när anropet är klart
manageCart("myId", functionToRunOnComplete, id);
}
function functionToRunOnComplete(id)
{
// use id...
}
// Detta är functionen som håller reda på kundvagnen
function manageCart(id, func, funcArg){
var url = 'ajax/cart.php';
var params = 'id=' + id;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params, onFailure: reportError, onComplete: func(funcArg)});
}
Vill man dock göra det komplicerat och vill kunna skicka in n antal argument till funktionen som körs när den är klar kan man göra såhär (överkurs):
function calc(id) {
manageCart( functionToRunOnComplete,"myid",id );
}
function functionToRunOnComplete(myid,id) //här kan du fånga vad du vill
{
//min rekomendation är dock att ha en check i funktionen iställetsom kollar vilka argument som kommer in och gör vad den ska avhängigt på det.
}
function manageCart( func, myid){
var url = 'foo.html';
alert(url)
var params = 'id=' + myid;
var ajax = new Ajax.Updater({success:'cartDIV'},url,{method: 'post', parameters: params,
onComplete: func.apply( Array.prototype.shift.call(arguments), arguments) });
}