我有一个带有文本编辑器的跷跷板UI。编辑器内容由一个名为"Task"的记录支持,该记录包含在称为"状态"的原子中的某个位置。编辑器上的键释放事件应更改任务的属性:d esc。我使用以下代码:
(def state
(atom {:tasks []
:interval nil
:style (style :foreground :black :background nil)}))
(defn on-text-edited [ui listener-fn]
(let [editor (select ui [:#editor])]
(listen editor :key-released
(fn [evt] (listener-fn (text editor))))))
(defn update-task! [task text]
(let [newtask (assoc task :desc text)
tasks (replace {task newtask} (:tasks @state))]
(swap! state
#(assoc % :tasks tasks))))
(def text-updates (on-text-edited frame #(update-task! selected-task %)))
选定任务是引用编辑器当前内容模型的原子。每当用户编辑文本时,更新任务!应该调用函数。但什么也没发生。该函数似乎根本没有被调用。当我从 repl 调用它时,它的行为符合预期。
我测试了该函数是否会通过让它执行简单的 println 来调用:
(defn update-task! [task text]
(println (str task " " text)))
现在,当我在编辑器中编辑文本时,该功能工作正常。然后我把它改成:
(defn update-task! [task text]
(let [newtask (assoc task :desc text)
tasks (replace {task newtask} (:tasks @state))]
(println (str task " " text))))
现在,它又什么也做不了。因此,似乎以某种方式访问原子会妨碍事件处理。ui 线程和定义原子的线程之间是否存在冲突?
它在简单情况下有效,在更复杂的情况下停止,我猜发生了异常,可能是在let
绑定中assoc
或replace
。根据开发环境,异常可能会隐藏,因为它发生在 UI 线程上。
我建议尝试调用 seesaw.dev/debug!
每当 UI 线程中抛出未经处理的异常时,它都会弹出一个带有堆栈跟踪的 UI。