2010-11-18 24 views
5

Das allgemeine Muster in AJAX-basierten UIs ist, dass wenn Benutzer eine Aktion ausführt, sofort in der Benutzeroberfläche angezeigt wird, aber bis zum Eintreffen der AJAX-Antwort als unfertig markiert ist. Dies ist z.B. Das Hinzufügen eines Termins in Google Kalender funktioniert. Und wenn ein Fehler auftritt, wird diese temporäre UI-Änderung rückgängig gemacht.jQuery AJAX "Hilfsprogramm rückgängig machen"

Nun, solche Reversion manuell ist nicht zu kreativ, so dass ich vermute, dass es einige "rückgängig Helfer" in jQuery, die den Zustand der UI-Elemente beibehalten und dann wiederherstellen - Art von Attribut-Stack oder etwas so wie das. Das muss nicht einmal etwas mit AJAX zu tun haben.

Gibt es so etwas?

Antwort

7

In solchen Situationen habe ich immer festgestellt, dass Staatsmaschinen der richtige Weg sind. Gestalten Sie Ihre Seite/Ihr JavaScript so, dass Sie zu jedem Zeitpunkt eine Reihe von Eingaben vornehmen können und Sie immer die gleiche Ausgabe über die gesamte Seite erhalten. Das Schöne an diesem Ansatz ist, dass Sie nicht wissen, wie Sie, wo Sie in Ihrem Programm sind, müssen Sie nur wissen, welche Daten in den aktuellen Zustand führte.

Für Ihren Fall könnten Sie ein grundlegendes Objekt beschreiben Ihren Zustand erstellen:

var state = { user: 'Tomasz', ajaxSent: false, otherState: 123 }; 

function updateFromState(state){ 
    // Set all dependent UI visibilities, etc. based on state object 
} 

Dann, bevor Sie Änderungen vornehmen, ihren aktuellen Zustand auf ein Array schieben, so dass Sie wieder bei Bedarf rückgängig machen können:

var stateList = []; 
stateList.push({ user: 'Tomasz', ajaxSent: false, otherState: 123 }); 

// Do something that changes your state 
var newState = {user: 'Tomasz', ajaxSent: true, otherState: 123 }; 
updateFromState(newState); 

// Now, if you need to revert 
var previousState = stateList.pop(); 
updateFromState(previousState); 

Der Nachteil dieses Ansatzes ist, dass Sie keine Nebenwirkungen "rückgängig machen", die Sie möglicherweise aufgerufen haben. Wenn Sie zum Beispiel einen AJAX-Post erstellt haben, der Daten auf dem Server geändert hat, müssten Sie verstehen, wie Sie diesen AJAX-Post rückgängig machen können. Dies geht über das Ändern des lokalen Status der Seite hinaus. Wenn Sie serverseitige Effekte nicht rückgängig machen müssen, sondern nur den korrekten Status der Seite wiedergeben können, funktioniert dies möglicherweise für Sie. Hier

ist, was würde ich wahrscheinlich um loszulegen verwenden, wenn ich so etwas wie dies tat:

var StateHelper = function(){ 
    var stateList = []; 
    var callbacks = []; 

    this.onChange = function(callback){ 
     callbacks.push(callback); 
    }; 

    this.set = function(opts){ 
     stateList.push(opts); 
     apply(opts); 
    }; 

    this.undo = function(){ 
     if(stateList.length <= 1){ 
      return; // nothing to undo 
     } 

     // To undo, we go back 2, since top of stack is current 
     stateList.pop(); 
     var last = stateList[stateList.length - 1]; 
     apply(last); 
    }; 

    var apply = function(opts){ 
     var length = callbacks.length; 
     for(var i = 0; i < length; i++){ 
      callbacks[i](opts); 
     } 
    }; 
}; 

Wenn dann meine Seite sieht wie folgt aus:

<div id='title' style='text-decoration: underline;'>some title</div> 
<div id='state1' class='clickable'>click to set state2 (title = 'second')</div> 
<div id='state2' class='clickable'>click to set state3 (title = 'third')</div> 
<br/> 
<div id='undo' class='clickable'>undo</div> 

Ich könnte die oben verwenden StateHelper wie folgt (man beachte ich einen Hauch von jQuery verwendet):

// A function that should be called when state changes 
var updateTitle = function(opts){ 
    // Update the pages title based on state 
    console.log('title updating'); 
    $('#title').text(opts.title); 
}; 

var myState = new StateHelper(); 
myState.onChange(updateTitle); // hook the state change event 

// some example states 
var state2 = { title: 'second' }; 
var state3 = { title: 'third' }; 

// Just some click handlers 
$(document).ready(function(){ 
    $('#state1').click(function(){ 
     myState.set(state2); 
    }); 

    $('#state2').click(function(){ 
     myState.set(state3); 
    }); 

    $('#undo').click(function(){ 
     myState.undo(); 
    }); 

    // Set initial state 
    myState.set({title: 'some title'}); 
}); 

Für Live-Beispiel finden Sie unter: http://jsfiddle.net/belorion/Hywtc/

+0

+1 für die sehr schön Antwort - Ich fühlte, dass mir eine so einfache Lösung fehlte. Tatsächlich bin ich hauptsächlich damit beschäftigt, DOM-Änderungen nach einer fehlgeschlagenen AJAX-Anfrage rückgängig zu machen, so dass keine serverseitigen Änderungen rückgängig gemacht werden können. –

+0

@Tomasz aktualisiert mit einem Code – Matt

+0

Ich bin noch nicht fertig mit all dem Zeug, aber es sieht aus wie eine Lösung für mein Problem, also akzeptiere ich Ihre Antwort jetzt. Vielen Dank! –

Verwandte Themen