如何在 flex 4 中实现 Undo Redo 操作以维护历史记录?我正在使用 flex UIComponent 和 DisplayObjects 来创建和编辑图表,但在 flex 中无法直接处理用户操作历史记录。有什么想法可以实现吗?
3 回答
您可以使用执行和撤消方法为所有操作实现命令模式,并将它们排队。
因此,当用户想要做某事时 - 可以说创建一个 AddFiveToTotal 类并执行:
public method execute():void{
totalModel.add( 5 );
}
然后,此类将存储在 FIFO 队列中。
如果用户需要撤消,则会弹出命令并调用撤消函数:
public method undo():void{
totalModel.subtract( 5 );
}
为了可重做性,不要弹出,只需迭代队列
还可以看看Memento Pattern
如果您正在使用任何当前流行的 MVC(S) 框架,您无疑会发现有人已经创建了一个实用程序
您可以在memento pattern
. 很难更好地跟踪所有属性,您可以了解哪些属性需要用于撤消/重做操作。
带有源代码的演示示例http://www.flairpy.com/mementoPattern/MementoSample.html
有几种方法可以解决这个问题。首先是将整个画布的状态保持在一个Vector
(我的意思是有一个监听器来监听用户在舞台上可以做的所有事情并在更改后保存状态),然后保存当前状态的索引,这样你就可以通过您的移动Vector
并将所需的状态放在舞台上。这是处理撤消/重做功能的最简单方法,但请注意,您必须大量克隆对象,如果您要处理大量对象或大量撤消,这将成为内存占用/重做。
第二种方法是只保留该向量中更改的内容,这样您就不必创建和克隆很多对象,而只需在其中保存一个对象,Vector
该对象将包含所有已更改的属性及其最后的值。这会给你这样的东西:
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
}
函数调用storeState
是这样的:
var state:Object = { name:DisplayObjectName, x:120, y:20 };
storeState(state);
同样,如果你想记录它们,你将不得不听所有的动作和变化。