如何取消/恢复对可观察模型的更改(或用未更改的副本替换数组中的模型)
我有一个 viewModel ,其中包含带有可观察变量的对象的 observableArray 。
我的模板使用编辑按钮显示数据,该按钮隐藏显示元素并显示具有绑定值的输入元素。您可以开始编辑数据,然后可以选择取消。我希望此取消恢复到对象的未更改版本。
我尝试通过执行类似以下操作来克隆对象:
viewModel.tempContact = jQuery.extend({}, contact);
或者
viewModel.tempContact = jQuery.extend(true, {}, contact);
但是 viewModel.tempContact 在联系后立即被修改。
KnockoutJS 中是否内置了任何内容来处理这种情况,或者我最好只创建一个具有完全相同详细信息的新联系人,并在取消时用新联系人替换修改后的联系人?
非常感谢任何建议。谢谢!
I have a viewModel with an observableArray of objects with observable variables.
My template shows the data with an edit button that hides the display elements and shows input elements with the values bound. You can start editing the data and then you have the option to cancel. I would like this cancel to revert to the unchanged version of the object.
I have tried clone the object by doing something like this:
viewModel.tempContact = jQuery.extend({}, contact);
or
viewModel.tempContact = jQuery.extend(true, {}, contact);
but viewModel.tempContact gets modified as soon as contact does.
Is there anything built into KnockoutJS to handle this kind of situation or am I best off to just create a new contact with exactly the same details and replace the modified contact with the new contact on cancel?
Any advice is greatly appreciated. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
有几种方法可以处理这样的事情。您可以构造一个与当前对象具有相同值的新对象,并在取消时将其丢弃。您可以添加其他可观察量以绑定到编辑字段并将它们保留在接受上或查看此 post 了解将此功能封装到可重用类型中的想法(这是我的首选方法)。
There are a few ways to handle something like this. You can construct a new object with the same values as your current one and throw it away on a cancel. You could add additional observables to bind to the edit fields and persist them on the accept or take a look at this post for an idea on encapsulating this functionality into a reusable type (this is my preferred method).
我在寻找解决类似问题时遇到了这篇文章,并认为我会为下一个人发布我的方法和解决方案。
我按照你的思路 - 克隆对象并在“撤消”上重新填充旧数据:
1)将数据对象复制到新的页面变量(“_initData”)
2)从原始服务器对象创建Observable
3) 在“撤消”时重新加载具有未更改数据的可观察对象(“_initData”)
简化的 JS:
var _viewModel;
var _initData = {};
我有一个足够复杂的对象,我不想为每个单独的属性添加处理程序。
实时对我的对象进行一些更改,这些更改同时编辑可观察对象和“_initData”。
当我从服务器获取数据时,我更新“_initData”对象以尝试使其与服务器保持同步。
I ran across this post while looking to solve a similar problem and figured I would post my approach and solution for the next guy.
I went with your line of thinking - clone the object and repopulate with old data on "undo":
1) Copy the data object into a new page variable ("_initData")
2) Create Observable from original server object
3) on "undo" reload observable with unaltered data ("_initData")
Simplified JS:
var _viewModel;
var _initData = {};
I had an object that was complicated enough that I didn't want to add handlers for each individual property.
Some changes are made to my object in real time, those changes edit both the observable and the "_initData".
When I get data back from the server I update my "_initData" object to attempt to keep it in sync with the server.
非常老的问题,但我只是做了一些非常类似的事情,并找到了一种非常简单、快速且有效的方法来使用映射插件来做到这一点。
背景;我正在编辑使用
foreach
绑定的 KO 对象列表。每个对象都使用一个简单的可观察对象设置为编辑模式,该可观察对象告诉视图显示标签或输入。这些函数设计用于每个
foreach
项的click
绑定中。然后,编辑/保存/取消很简单:
这在编辑简单对象列表时非常有用,尽管在大多数情况下我发现自己有一个包含轻量级对象的列表,然后加载完整的详细模型以进行实际编辑,所以这个问题不会出现。
如果您不喜欢这样添加
__undo
属性,您可以向模型添加saveUndo
/restoreUndo
方法,但我个人认为这是方式更清晰,代码也少得多,并且可以在任何模型上使用,即使是没有显式声明的模型。Very old question, but I just did something very similar and found a very simple, quick, and effective way to do this using the mapping plugin.
Background; I am editing a list of KO objects bound using a
foreach
. Each object is set to be in edit mode using a simple observable, which tells the view to display labels or inputs.The functions are designed to be used in the
click
binding for eachforeach
item.Then, the edit / save / cancel is simply:
This is very useful when editing lists of simple objects, although in most cases I find myself having a list containing lightweight objects, then loading a full detail model for the actual editing, so this problem does not arise.
You could add
saveUndo
/restoreUndo
methods to the model if you don't like tacking the__undo
property on like that, but personally I think this way is clearer as well as being a lot less code and usable on any model, even one without an explicit declaration.您可以考虑使用 KO-UndoManager 来实现此目的。下面是注册视图模型的示例代码:
然后,您可以在 html 中添加撤消/重做按钮,如下所示:
和 这里是 Plunkr 展示它的实际应用。要撤消所有更改,您需要在 JavaScript 中循环调用
undoMgr.undoCommand.execute
,直到撤消所有更改。You might consider using KO-UndoManager for this. Here's a sample code to register your viewmodel:
You can then add undo/redo buttons in your html as follows:
And here's a Plunkr showing it in action. To undo all changes you'll need to loop call
undoMgr.undoCommand.execute
in javascript until all the changes are undone.我需要类似的东西,但我无法使用受保护的可观察量,因为我需要计算来更新临时值。所以我写了这个淘汰扩展:
这个扩展创建了每个可观察的下划线版本,即 self.Comments() -> self._Comments()
这个扩展将节省您编写每个可观察量的重复项并忽略您的计算值。它的工作原理如下:
正如您所看到的,如果 html 上有按钮:
“取消”将撤消您的可观察值并将其恢复到原来的状态,就像“保存”将使用一行中的临时值更新实际值
I needed something similar, and I couldn't use the protected observables, as I needed the computed to update on the temporary values. So I wrote this knockout extension:
This extension creates an underscore version of each observable ie self.Comments() -> self._Comments()
This extension will save you writing duplicates of each of your observables and ignores your computed. It works like this:
So as you can see if you have buttons on html:
Cancel will undo and revert your observables back to what they were, as were save will update the real values with the temp values in one line