我有一个用reagent/create-class
创建的组件,该组件获得了subscribe
创建的原子。我在:component-did-mount
上添加了一个手表,以便根据请求调用组件(js)函数,该函数是由原子的变化触发的(有服务器往返)。它看起来如下:
(defn editor [text issue-hints]
(let []
(reagent-core/create-class
{:component-did-mount
#(let [editor (js/SimpleMDE.
(clj->js {...}))]
(do
...
(add-watch issue-hints :watch-issue-hints (show-hint (-> editor .-codemirror)))
...))
:reagent-render
(fn [this] [:textarea])})))
(defn edit-panel [text]
(let [test (re-frame.core/subscribe [:issue-hints])]
[box
:class "issue-detail"
:size "auto"
:child [:div.issue-detail [editor text test]]]))
它在调试项目时效果很好,但是一旦运行uberjar文件,就不会调用监视处理程序。对我来说,最奇怪的是,如果至少添加了对预订原子的虚拟引用,它又可以很好地工作(例如,与预订相同的let中的dummy @issue-hints
)。服务器往返看起来不错。
有人可以给我一些解释和/或建议,以获得更合理的解决方案/解决方法吗?
答案 0 :(得分:0)
您似乎需要在:reagent-render
中使用两个参数,而不是一个-
:reagent-render
(fn [text issue-hints] [:textarea])}))) ---> Not "this", but should match initial args
当您仅传递一个arg并且未在component-did-mount
fn中取消引用时,它在后续更改中将不会收到预订。
此外,我认为您无需显式使用add-watch
,因为re-frame
订阅可以为您提供服务。通过使用deref语法@issue-hints
,只要issue-hints
发生更改,该元素就会得到通知,并且您应该能够从app-db
观察状态。
如果添加第二个arg,我的猜测是您可以放下add-watch
,它应该可以正常工作。
这里是docs,如果您看一下代码示例,就会看到args的重复...
----- Edit: Will Form-2 work? -----
(defn editor [text issue-hints]
(let [hints @issue-hints
editor (js/SimpleMDE. (clj->js {...})] ;;-> This will not be dynamic, so consider moving to returned fn if necessary
(fn [text issue-hints]
(if hints
[:textarea (special-hint-handler hints)]
[:textarea]
))))
因此,根据评论,这将为您提供watcher
上的issue-hints
,您可以做出相应的回应。订阅不一定需要在DOM上使用。