基于AJAX的UI中的常见模式是,当用户执行操作时,它会立即反映在UI中,但在到达AJAX响应确认一切正常之前标记为未完成.这就是在Google日历中添加活动的方式.当出现错误时,将恢复临时UI更改.
现在,手动进行这样的回归并不是太有创意,所以我怀疑jQuery中有一些"撤消助手",它允许保留UI元素的状态,然后恢复它 - 一种属性堆栈或类似的东西.这甚至不必与AJAX有任何关系.
有什么相似的吗?
在这种情况下,我总是发现状态机是可行的方法.设计您的页面/ JavaScript,以便在任何时间点您都可以指定一组输入,并且您将始终在整个页面上获得相同的输出.这种方法的好处是你不知道你如何到达你的程序中的位置,你只需要知道当前状态产生了什么数据.
对于您的情况,您可以创建一个描述您的州的基本对象:
var state = { user: 'Tomasz', ajaxSent: false, otherState: 123 };
function updateFromState(state){
// Set all dependent UI visibilities, etc. based on state object
}
Run Code Online (Sandbox Code Playgroud)
然后,在进行任何更改之前,将当前状态推送到阵列,以便在需要时可以恢复:
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);
Run Code Online (Sandbox Code Playgroud)
这种方法的缺点是你实际上并没有"撤消"你可能调用过的任何副作用.例如,如果您在服务器上创建了修改数据的AJAX帖子,则必须了解如何"撤消"该AJAX帖子.这不仅仅是改变页面的本地状态.但是,如果您不需要撤消服务器端效果,但只是能够准确反映页面的正确状态,这可能对您有用.
如果我做这样的事情,我可能会开始使用以下内容:
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);
}
};
};
Run Code Online (Sandbox Code Playgroud)
然后,如果我的页面看起来像这样:
<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>
Run Code Online (Sandbox Code Playgroud)
我可能会像这样使用上面的StateHelper(注意我使用了一点jQuery):
// 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'});
});
Run Code Online (Sandbox Code Playgroud)
有关实例,请参阅:http://jsfiddle.net/belorion/Hywtc/