我一直在尝试找出允许 JavaFX TableView(或任何其他 JavaFX 事物)表示一些 Clojure 数据并允许用户通过 GUI 操作数据的方法。
对于本次讨论,假设我有一个地图列表/矢量,例如
[{:col1 "happy1" :col2 "sad1"} {:col1 "happy2" :col2 "sad2"}]
,我希望它显示在图形表中,如下所示:
mykey1 mykey2
------------------
happy1 sad1
happy2 sad2
很简单。这在世界历史上已经完成了无数次。
问题是 TableView 坚持要取一个 ObservableList 等,这本质上是一个可变的东西,JavaFX 中的所有 Observable 也是如此。这对于使表保持最新非常有用,并且在可变模型中,对于允许用户通过 GUI 直接操作数据也非常有用。我不是专家,但在这种情况下,JavaFX 似乎希望 GUI 对象实际包含真实数据。这对我来说似乎很有趣(不是哈哈)。维护我自己的模型并通过一些 API 或接口在 GUI 和模型之间进行通信也意味着我在两个地方维护数据:在我自己的模型中和在 GUI 中。这是正确的做事方式吗?也许这没关系,因为 GUI 只显示总数据的一小部分,它让我的模型数据只是普通的模型数据,
因此,当尝试将 GUI 置于无状态/不可变模型上时,这会导致以下三个一般问题:
如果 GUI 必须允许您更改事物,那么下面的模型如何才能真正不可变?我正在特别考虑某种设计工具、编辑器等,用户在其中明确地改变事物。例如 LightTable 是一个编辑器,但故事是它基于不可变数据。怎么会这样?我对这次讨论的 FRP 不感兴趣。
假设在某个级别上至少存在一个
Atom
或其他 Clojure 可变类型(ref/var/agent/etc)(无论是Atom
包含整个内存设计数据库的单个,还是设计数据库是 mutable 的不可变列表Atoms
) , [MVP, MCP, MVVM, etc.] 模型中哪一个最适合这种类型的创作?JavaFX 用 Observable 接口 ( http://docs.oracle.com/javafx/2/api/javafx/beans/Observable.html ) 的每一个可以想象的变体来散布类层次结构
Observable[whatever]Value
,其中包括ObservableMap
和ObservableMapValue
,以及然后是几十个实现类,比如IntegerProperty
和SimpleIntegerProperty
......天哪!wtf?。假设我必须创建一些 Clojure 对象(defrecord
等)并Observable
在我的大部分不可变对象上实现一些接口方法,我可以坚持使用Observable
,还是必须将每个方法都实现到叶节点,即ObservableIntegerValue
等?
什么是正确的高级方法?维护一个每次用户更改值时都会被替换的顶级原子?维持一千个低级原子?让我的值作为 JavaFX Observables 存在,而忘记 Clojure 数据结构?使用一些 reify/proxy/gen-class 在 Clojure 中实现我自己的一组 Observables,但是将它们实现为每次更改时都会被替换的不可变对象?Clojure 的功能是否有需要或地方add-watch
?我非常希望我的数据只是 Clojure 中的普通数据,而不是“类型”或任何接口的实现。整数应该是整数等。
谢谢