Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.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 如何使用undo创建可观察数组?_Javascript_Jquery_Knockout.js - Fatal编程技术网

Javascript 如何使用undo创建可观察数组?

Javascript 如何使用undo创建可观察数组?,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,我正在尝试添加淘汰JS到我们网站上的搜索页面。目前,您打开了一个jQuery对话框,其中有许多可供选择的条件复选框 存在具有多种类型条件的多个对话框。当您打开对话框时,复选框在您点击“更新”按钮之前不会生效。如果您单击“取消”或仅关闭窗口,您所做的更改将恢复,并且对话框将设置为以前的状态 我读了一些其他的帖子。然而,这似乎只适用于ko.observable,我似乎无法让它适用于ko.observableArray 有没有人做到了这一点或有什么想法 我想做的一个例子: Html: 男性 女性 取

我正在尝试添加淘汰JS到我们网站上的搜索页面。目前,您打开了一个jQuery对话框,其中有许多可供选择的条件复选框

存在具有多种类型条件的多个对话框。当您打开对话框时,复选框在您点击“更新”按钮之前不会生效。如果您单击“取消”或仅关闭窗口,您所做的更改将恢复,并且对话框将设置为以前的状态

我读了一些其他的帖子。然而,这似乎只适用于
ko.observable
,我似乎无法让它适用于
ko.observableArray

有没有人做到了这一点或有什么想法

我想做的一个例子:

Html:


男性
女性
取消
更新
Javascript:

var viewModel = {
    genders: ko.observableArrayWithUndo([])
};

ko.applyBindings(viewModel);

$('#buttonCancel').click(function(){
   viewModel.genders.resetChange();
});

$('#buttonUpdate').click(function(){
    viewModel.genders.commit();
    return false;
});

以下是一种方法:

//wrapper to an observableArray of primitive types that has commit/reset
ko.observableArrayWithUndo = function(initialArray) {
    var _tempValue = ko.observableArray(initialArray.slice(0)), 
        result = ko.observableArray(initialArray);

    //expose temp value for binding
    result.temp = _tempValue;

    //commit temp value
    result.commit = function() {
        result(_tempValue.slice(0));
    };

    //reset temp value
    result.reset = function() {
        _tempValue(result.slice(0)); 
    };

    return result;
};
您可以将复选框绑定到yourName.temp,将UI的另一部分绑定到yourName

以下是一个示例:

切片(0)是获取数组的浅层副本(甚至只是切片())的一种方法。否则,您将对同一数组的引用执行操作

给定的HTML类似于:

<div>
    <button data-bind="click: function() { undo(); }">Undo</button>
    <input data-bind="value: firstName" />
    <input data-bind="value: lastName" />
    <textarea data-bind="value: text"></textarea>
</div>
我这里有一个N级撤销和敲除的示例:

您可能能够适应您的使用

//current state would probably come from the server, hard coded here for example
var currentState = JSON.stringify({
    firstName: 'Paul',
    lastName: 'Tyng',
    text: 'Text' 
})
   , undoStack = [] //this represents all the previous states of the data in JSON format
    , performingUndo = false //flag indicating in the middle of an undo, to skip pushing to undoStack when resetting properties
    , viewModel = ko.mapping.fromJSON(currentState); //enriching of state with observables


//this creates a dependent observable subscribed to all observables 
//in the view (toJS is just a shorthand to traverse all the properties)
//the dependent observable is then subscribed to for pushing state history
ko.dependentObservable(function() {
    ko.toJS(viewModel); //subscribe to all properties    
}, viewModel).subscribe(function() {
    if(!performingUndo) {
    undoStack.push(currentState);
    currentState = ko.mapping.toJSON(viewModel);
}
});

//pops state history from undoStack, if its the first entry, just retrieve it
    window.undo = function() {
        performingUndo = true;
        if(undoStack.length > 1)
        {
            currentState = undoStack.pop();
            ko.mapping.fromJSON(currentState, {}, viewModel);
        }
        else {
            currentState = undoStack[0];
            ko.mapping.fromJSON(undoStack[0], {}, viewModel);
        }
        performingUndo = false;
};

ko.applyBindings(viewModel);