JavaFX и Clojure: привязка наблюдаемых к неизменным объектам
Я пытался выяснить подход, чтобы позволить JavaFX TableView (или любому другому JavaFX) представлять некоторые данные Clojure и позволить пользователю манипулировать данными через графический интерфейс.
Для этого обсуждения давайте предположим, что у меня есть список / вектор карт, то есть что-то вроде [{:col1 "happy1" :col2 "sad1"} {:col1 "happy2" :col2 "sad2"}]
и я хочу, чтобы это отображалось в графической таблице следующим образом:
mykey1 mykey2
------------------
happy1 sad1
happy2 sad2
Довольно просто. Это было сделано миллиард раз в мировой истории.
Проблема заключается в том, что TableView настаивает на использовании ObservableList и т. Д., Что по сути является изменчивой вещью, как и все Observables в JavaFX. Это отлично подходит для поддержания таблицы в актуальном состоянии, а в изменчивой модели она также отлично подходит для того, чтобы позволить пользователю напрямую манипулировать данными через графический интерфейс. Я не эксперт, но в этом случае кажется, что JavaFX хочет, чтобы объект GUI действительно содержал реальные данные. Это кажется смешным (не ха-ха) для меня. Поддержание моей собственной модели и связи между GUI и моделью через некоторый API или интерфейс также подразумевает, что я поддерживаю данные в двух местах: в моей собственной модели и в GUI. Это правильный способ делать вещи? Возможно, это нормально, поскольку графический интерфейс отображает лишь небольшую часть от общих данных, и он позволяет моим модельным данным быть просто обычными модельными данными, а не экземпляром какого-либо типа, производного от Java.
Таким образом, это приводит к следующим трем общим вопросам при попытке установить графический интерфейс для модели без состояния / неизменности:
Как модель может быть действительно неизменной, если графический интерфейс обязательно позволяет вам что-то менять? Я имею в виду какой-то инструмент проектирования, редактор и т. Д., Где пользователь явно меняет все вокруг. Например, LightTable - это редактор, но история в том, что он основан на неизменных данных. Как это может быть? Я не заинтересован в FRP для этого обсуждения.
Предполагая, что на каком-то уровне есть хотя бы один
Atom
или другой изменяемый тип Clojure (ref/var/agent/etc) (будь то одиночныйAtom
содержит всю базу данных проектирования в памяти или является ли база данных проектирования неизменным списком изменяемыхAtoms
), какая из моделей [MVP, MCP, MVVM и т. д.] лучше всего подходит для этого типа творения?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? Реализовать мой собственный набор Observables в Clojure с использованием некоторого reify/proxy/gen-class, но реализовать их как неизменяемые, которые заменяются каждый раз, когда вносятся изменения? Есть ли необходимость или место для Clojure? add-watch
функционировать? Я бы очень предпочел, чтобы мои данные были просто обычными данными в Clojure, а не "типом" или реализацией интерфейса чего-либо. Целое число должно быть целым числом и т. Д.
Спасибо
1 ответ
Я бы добавил часы к атому, а затем обновил бы вашу наблюдаемую на основе различий. http://clojuredocs.org/clojure.core/add-watch