Prototype - onSuccess
juppinger
- javascript
Hallo,
kann mir jemand sagen, wie ich hier mit Prototype 2 oder mehrere Funktionen ausführen kann?
Ich führe ein Ajax-Kommando aus (für z.B. Laden und Speichern von Daten in einer Funktion) und sage der Funktion noch, welche Funktion beim onComplete ausgeführt werden soll. Problematik hier besteht darin, dass beim Laden an die Funktion onComplete noch das Objekt "originalRequest", also die Daten mit angehängt werden.
Ich würde jetzt gerne noch einen Spinner (Ladebalken) anzeigen, an einer dynamischen Stelle...
Das funktioniert (ohne Spinner):
---------------------------------
function ajax_action(url,command,data,fnOnComplete) {
var data = 'cmd=' + command + '&' + data;
var myAjax = new Ajax.Request (
url,
{
method: 'post',
parameters: data,
onComplete: fnOnComplete
}
);
}
So in etwa soll es dann sein (klappt nicht):
-----------------------------------------------
function ajax_action(url,command,SHOWspinnerdiv,HIDEcontentdiv,data,fnOnComplete) {
SHOWspinnerdiv.show();
HIDEcontentdiv.hide();
var data = 'cmd=' + command + '&' + data;
var myAjax = new Ajax.Request (
url,
{
method: 'post',
parameters: data,
onComplete: function() {
fnOnComplete;
SHOWspinnerdiv.hide();
HIDEcontentdiv.show();
}
}
);
}
Danke für jeden Tipp.
Gruß,
juppinger
Hallo juppinger,
anhand Deiner Beschreibung steht man etwas vor dem Berg und weiss nicht wirklich, was Du meinst, was Du willst und was gegen Deine Erwartung schief läuft.
kann mir jemand sagen, wie ich hier mit Prototype 2 oder mehrere Funktionen ausführen kann?
Mit einer anonymen Funktion, die beide kapselt.
Ich führe ein Ajax-Kommando aus (für z.B. Laden und Speichern von Daten in einer Funktion) und sage der Funktion noch, welche Funktion beim onComplete ausgeführt werden soll. Problematik hier besteht darin, dass beim Laden an die Funktion onComplete noch das Objekt "originalRequest", also die Daten mit angehängt werden.
Hier klingt das so, als willst Du in der Funktion die beim Pseudo-Event onComplete
an irgendwelche Daten rankommen. originalRequest lässt auf etwas vor Abschicken des Requests schliessen, diese Daten sind zum Zeitpunkt des Definierens des Ajax-Objekts verfügbar. Die Beschreibung desselben lässt auf die vom Server zurückgelieferten Daten schliessen. Diese hast Du in Deiner Funktion als ersten Parameter zu Verfügung: laut Dokumentation ist der erste Parameter einer Event-Handler-Funktion immer das klassische XmlHttpRequest-Objekt. Allerdings nützt Dir das nur, wenn überhaupt Daten mitgeliefert werden. Der Event-Handler onComplete
wird immer ausgeführt, wenn ein Request zu Ende ist. Er sagt Dir nicht, ob dieser Request erfolgreich war und ob die Response Daten mitgeliefert hat. Deswegen solltest Du besser den onSuccess
nehmen (Steht auch so in der Doku). Ungefähr so:
~~~javascript
var req = new Ajax.request(url, {
method: "post",
parameters: data,
onSuccess: function (xhr) {
// xhr ist hier das klassische XMLHttpRequest-Objekt
// Wenn es XML ist, kann man die Daten bequem als XML kriegen
xmldata = xhr.responseXML;
// Wenn nicht, dann als reinen Text:
plaindata = xhr.responseTest;
tueWasMit(xmldata, plaindata);
},
onFailure: function (xhr) {
// Guter Stil ist es, den Fehlerfall auch zu behandeln.
}
});
> Ich würde jetzt gerne noch einen Spinner (Ladebalken) anzeigen, an einer dynamischen Stelle...
> So in etwa soll es dann sein (klappt nicht):
(Du schreibst nicht, was genau nicht klappt. Verwirrend.)
> function ajax\_action(url,command,SHOWspinnerdiv,HIDEcontentdiv,data,fnOnComplete) {
> ... Gekürzt ...
> onComplete: function() {
> fnOnComplete;
Vermutlich hier dran - schliesslich geschieht kein Aufruf der Funktion fnOnComplete. `Ajax.onComplete`{:.language-javascript} musst Du eine Referenz auf eine Funktion zuweisen. Das geschieht entweder mit dem Namen (eine Referenz) auf eine Funktion – dann und nur dann musst Du eine Funktion ohne die Aufruf-Klammern („()“) schreiben oder aber in einer anonymen Funktion wie hier. Innerhalb dieser anonymen Funktion ist dann aber wieder business as usual, d.h. wenn man etwas aufrufen will, braucht man die Klammern.
Ich würde Dein Ding so umschreiben, immer angenommen, Du brauchst alle Parameter so dynamisch, dass Du sie bei jedem Aufruf der Funktion neu ändern kannst:
~~~javascript
function ajaxAction (url, command, spinner, content, data, fnOnComplete) {
// Dieses hier ...
// var data = 'cmd=' + command + '&' + data;
// ... ändere ich mal eben leichtherzig in das hier:
var p = $H({
cmd: command,
data: data,
});
// Sieht komplizierter aus, ist es aber nicht wirklich. Ich habe die Erfahrung
// gemacht, dass es zu nervig ist, URL-Parameter händisch per String
// zusammenzubasteln, all das Escape, besser man überlässt das dem Programm,
// das das für einen macht. Die Ajax-Option 'parameters' von prototype nimmt
// neben einem Query-String auch Hashes entgegen und baut daraus dann den
// passenden Query-String zusammen. Sähe dann ungefähr so aus:
//
// ?cmd=command&data=data
//
// Mit den entsprechenden maskierten Werten für command und data dann
// natürlich - und ich gehe davon aus, dass data ein String ist. Hashes
// haben auch den Vorteil, dass man sie dynamisch befüllen kann.
// (Das ganze ist nur eine persönliche Vorliebe von mir.)
var req = new Ajax.Request(url, {
method: 'post',
parameters: p,
onCreate: function () {
// onCreate wird beim Erstellen des Ajax-Objektes aufgerufen.
spinner.show();
content.hide();
},
// Bei Erhalt der Daten wird das hier aufgerufen:
onSuccess: function (xhr) {
fnOnComplete(xhr);
},
// ... das nicht unbedingt in einer anonymen Funktion notiert sein muss,
// wenn Du nur onSuccess: fnOnComplete notierst, wird auch fnOnComplete
// mit dem XMLHttpRequest-Objekt als ersten Parameter aufgerufen.
// Auch den Fehlerfall beachten:
onFailure: tueEtwas,
// Auf jeden Fall, egal ob erfolgreich oder nicht, sollte am Ende
// das nervige Drehding gestoppt und der Inhalt wieder eingeblendet werden
onComplete: function () {
spinner.hide();
content.show();
},
});};
Wenn Deine mysteriöse fnOnComplete-Funktion das tut, was ich denke – erhaltenen Content in das content-Div einfügen, solltest Du Dir auf jeden Fall noch prototypes Ajax.Updater angucken; für Einfügen von Zeug ist das prädestiniert.
Tim