使用 reagent 和 re-frame 时,如何在 crud 类型的应用程序中实现撤消和重做?

How to implement undo and redo in a crud type of application when using reagent and re-frame?

尽管在 re-frame 主页上说 "Save and Undo become quite easy.",re-frame 示例应用程序 'todomvc' 没有实现撤消/重做功能的代码。

当使用像 Java 这样的 OO 语言时,通常的做法是通过对执行的操作使用命令接口来实现撤消/重做,将它们与它们的 'inverses' 一起存储并(重新)执行它们来自存储的命令对象的集合。

虽然我已经阅读了常见 OO 设计模式的 Clojure 等价物页面 including, Command here.,但在某些示例或应用程序中看到使用 reagent、re-frame 实现的撤消/重做会很有帮助。

问。 如何在crud类型的应用程序中使用reagent和re-frame实现undo和redo?

其中一种方法是仅存储状态历史记录 - 这将节省内存,因为 Clojure(Script) 实际上会将其存储为引擎盖下的更改历史记录。

请参阅 this link 以获得非常简短明了的示例!

Re-frame 实际上有一个内置的 undoable 处理程序中间件。不幸的是,(否则很出色)文档根本没有涵盖它;我是看源码才明白的。

使用起来非常简单:

(register-handler :your-handler
  ; this middleware from re-frame.core is all you need to enable undo
  (undoable "String that explains your action, optional")
  (fn [db [_]] ...))

完成后,如果您想撤消操作,只需 (dispatch [:undo])。要重新应用操作,它是 (dispatch [:redo]).

中间件通过在每次调用之间简单地保存 app-db 的变异版本来在后台工作。默认最大撤消深度为 50。

有关详细信息,请阅读 this file and this one