Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jqueryajax";“撤消辅助对象”;_Javascript_Jquery - Fatal编程技术网

Javascript jqueryajax";“撤消辅助对象”;

Javascript jqueryajax";“撤消辅助对象”;,javascript,jquery,Javascript,Jquery,基于AJAX的UI中的常见模式是,当用户执行一个动作时,它会立即反映在UI中,但在到达AJAX响应确认一切正常之前,它会被标记为未完成。这就是在Google日历中添加事件的工作方式。当出现错误时,该临时UI更改将恢复 现在,手动执行这样的恢复不是很有创意,所以我怀疑jQuery中有一些“撤销助手”,它允许保留UI元素的状态,然后恢复它——类似于属性堆栈之类的东西。这甚至与AJAX没有任何关系 有类似的情况吗?在这种情况下,我总是发现状态机是一种可行的方法。设计页面/JavaScript时,您可以

基于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
}
然后,在进行任何更改之前,将当前状态推送到阵列上,以便在需要时恢复:

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);
这种方法的缺点是,您实际上并没有“撤销”您可能调用的任何副作用。例如,如果您制作了一篇修改服务器上数据的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);
        }
    };
};
<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>

有关实时示例,请参见:

记录-受Matt答案的启发,我编写了一小段代码,可以自动反转CSS更改:


+1非常好的答案-我觉得我错过了这么简单的解决方案。事实上,我最关心的是在AJAX请求失败后撤消DOM更改,因此没有服务器端更改可恢复。我还没有完全了解这些内容,但这似乎是我问题的解决方案,所以我现在接受你的答案。谢谢@Tomasz,关于上面的代码你有什么特别的问题吗?不,我粗略地理解它,但是我正处于学习JavaScript内部工作的中间,所以当我看到诸如“代码> {} /代码>之类的东西时,我不认为“哦,它只是一个对象!”但是我更喜欢在阴影中看到发生了什么。这会分散我对顶级内容的注意力:-)
// 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'});
});