简体   繁体   English

在Flex中实施撤消重做

[英]Implement an Undo Redo in flex

How to implement Undo Redo operation in flex 4 for maintain history? 如何在Flex 4中实施撤消重做操作以维护历史记录? I'm working with flex UIComponent and DisplayObjects for creating and editing diagrams,but in flex there is no way to handle user operation history directly. 我正在使用flex UIComponent和DisplayObjects来创建和编辑图,但是在flex中,无法直接处理用户操作历史记录。 there is any idea to achieve this? 有什么想法可以实现这一目标吗?

You could implement the Command Pattern for all actions with execute and undo methods, and queue them up. 您可以使用execute和undo方法为所有操作实现命令模式 ,并将它们排队。

so when the user wants to do some thing - lets say create an AddFiveToTotal class and executes: 因此,当用户想要做某事时-可以说创建一个AddFiveToTotal类并执行:

public method execute():void{
     totalModel.add( 5 );
}

This class would then be stored on a FIFO queue. 然后将此类存储在FIFO队列中。

if the user needs to undo the command would be popped and the undo function called: 如果用户需要撤消该命令,则会弹出该命令,撤消函数称为:

public method undo():void{
     totalModel.subtract( 5 );
}

for redoability, don't pop, just iterate the queue 为了重做,不要弹出,只需要迭代队列

also take a look at the Memento Pattern 还看一看Memento模式

If you are using any of the currently popular MVC(S) frameworks you will undoubtably find a util that some one has already created 如果您正在使用任何当前流行的MVC(S)框架,则无疑会找到某个已经创建的实用程序。

You can acheive with help of memento pattern . 您可以借助memento pattern It hard to track all properties better you can what are property need to use for undo/redo operation. 可以更好地跟踪所有属性,您可以确定撤消/重做操作需要使用哪些属性。

Memento Design pattern 纪念品设计模式

Memento pattern 纪念图案

Demo sample with source code http://www.flairpy.com/mementoPattern/MementoSample.html 带有源代码的演示示例http://www.flairpy.com/mementoPattern/MementoSample.html

There are several ways you can address to this problem. 有几种方法可以解决此问题。 First is to keep the states of your whole canvas in a Vector (I mean have a listener for all the things user can do on the stage and saving the state after a change) and then have an index of current state saved, so that you could move through your Vector and put the needed state on the stage. 首先是将整个画布的状态保存在Vector (我的意思是让用户监听舞台上用户可以做的所有事情,并在更改后保存状态),然后保存当前状态的索引,以便您可以遍历您的Vector并将所需的状态放在舞台上。 This is the easiest way to approach undo/redo functionality, but beware that you'll have to make clones of objects a lot and this will become a memory hog if you're going to deal with a lot of objects or a lot of undo/redos. 这是实现撤消/重做功能的最简单方法,但是请注意,您将不得不大量复制对象,如果您要处理大量对象或执行大量撤消操作,这将成为内存浪费。 / redos。

The second approach is to only keep what changed in that vector, so that you won't have to create and clone a lot of objects, but only save one object in your Vector which will contain all the properties that have changed and their last values. 第二种方法是只保留矢量中已更改的内容,这样您就不必创建和克隆很多对象,而只需在Vector保存一个对象,该对象将包含所有已更改的属性及其最后的值。 This will get you something like this: 这将为您提供以下信息:

private var mHistory:Vector.<Object> = new Vector.<Object>();
private var mCurrentIndex:int = -1;

public function storeState(state:Object)
{
   mHistory.push(state);
   mCurrentIndex++;
}     

public function undo():void
{
   if(mCurrentIndex < 1)
       return;

   mCurrentIndex--;

   //here you could test for values that could have changed
   var item:DisplayObject = this.getChildByName(mHistory[mCurrentIndex].name);
   if(mHistory[mCurrentIndex].x != undefined)
       item.x = mHistory[mCurrentIndex].x;
   // etc. you get the point. Note that this is only comfortable if only several things can change
}

And the call for storeState function would be like this: storeState函数的调用将如下所示:

var state:Object = { name:DisplayObjectName, x:120, y:20 };
storeState(state);

Again, you will have to listen to all movement and changes if you want to record them. 同样,如果要记录所有的运动和变化,则必须聆听它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM