为组件数据中缺少的键设置初始状态
Set initial state for missing key in component data
我正在尝试学习 ClojureScript 和 Om。有一个具体案例让我运行圈了起来。
我有一个在没有密钥的情况下首次呈现的组件。
(defn model-view [data owner]
(reify
om/IWillMount
(will-mount [_]
(om/transact! data [:stats] (fn [] {}))
(go
(let [response ((<! (api/get-stats (data :id))) :body)
stats (:stats response)]
(om/update! data [:stats] stats))))
om/IRender
(render [_]
(dom/div nil
(dom/h3 nil (data :title))
;; Here I want to use the :stats key in data that I
;; queried for in IWillMount, but its not present
;; the first time this model is rendered. It's only present
;; AFTER IWillMount has ran.
(om/build model-stats-view (data :stats)))))
第一次调用此组件时,:stats
键根本不存在于 data
中。这就是为什么我调用 API 来获取其统计信息的原因。但 React 仍然调用 render
函数,因此组件崩溃。
如何在此组件中设置初始状态,为 data
提供一个名为 :stats
的空地图,从而防止在 (om/build model-stats-view)
调用中尝试渲染 nil
?
我更喜欢在初始状态下进行所有初始化,然后在呈现状态下访问它。我在我的 did-mount 中放了一个 go-loop。当您在 go-loop 中更新您的初始状态(即:e-map)时,它会强制调用组件的 render/re-render。我在我的所有组件中都使用它来进行 inter-component/intra-component 消息传递。只需将内容推送到 pub/sub 频道,我们就可以开始比赛了。
;To update my state I use a function:
(defn set-owner-state! [owner old-map-key old-map new-map]
(om/set-state! owner {old-map-key (merge old-map new-map)}))
om/IInitState
(init-state [_]
(println "queue->init-state")
{:e-map {:active-fsm nil}})
om/IDidMount
(did-mount [_]
(go-loop []
(let [[v _] (alts! [server-fsm-events dispatcher-events])
current-state (om/get-state owner)
e-map (:e-map current-state)]
; what goes in here is the logic to respond to a message
; in my case I have a match, it could be a cond or a set of
; if's.
(set-owner-state! owner :e-map e-map {:active-fsm :active :task-paths nil})
...
om/IRenderState
(render-state [_ {:keys [e-map]}]
(println "e-map:" e-map)
...
我正在尝试学习 ClojureScript 和 Om。有一个具体案例让我运行圈了起来。
我有一个在没有密钥的情况下首次呈现的组件。
(defn model-view [data owner]
(reify
om/IWillMount
(will-mount [_]
(om/transact! data [:stats] (fn [] {}))
(go
(let [response ((<! (api/get-stats (data :id))) :body)
stats (:stats response)]
(om/update! data [:stats] stats))))
om/IRender
(render [_]
(dom/div nil
(dom/h3 nil (data :title))
;; Here I want to use the :stats key in data that I
;; queried for in IWillMount, but its not present
;; the first time this model is rendered. It's only present
;; AFTER IWillMount has ran.
(om/build model-stats-view (data :stats)))))
第一次调用此组件时,:stats
键根本不存在于 data
中。这就是为什么我调用 API 来获取其统计信息的原因。但 React 仍然调用 render
函数,因此组件崩溃。
如何在此组件中设置初始状态,为 data
提供一个名为 :stats
的空地图,从而防止在 (om/build model-stats-view)
调用中尝试渲染 nil
?
我更喜欢在初始状态下进行所有初始化,然后在呈现状态下访问它。我在我的 did-mount 中放了一个 go-loop。当您在 go-loop 中更新您的初始状态(即:e-map)时,它会强制调用组件的 render/re-render。我在我的所有组件中都使用它来进行 inter-component/intra-component 消息传递。只需将内容推送到 pub/sub 频道,我们就可以开始比赛了。
;To update my state I use a function:
(defn set-owner-state! [owner old-map-key old-map new-map]
(om/set-state! owner {old-map-key (merge old-map new-map)}))
om/IInitState
(init-state [_]
(println "queue->init-state")
{:e-map {:active-fsm nil}})
om/IDidMount
(did-mount [_]
(go-loop []
(let [[v _] (alts! [server-fsm-events dispatcher-events])
current-state (om/get-state owner)
e-map (:e-map current-state)]
; what goes in here is the logic to respond to a message
; in my case I have a match, it could be a cond or a set of
; if's.
(set-owner-state! owner :e-map e-map {:active-fsm :active :task-paths nil})
...
om/IRenderState
(render-state [_ {:keys [e-map]}]
(println "e-map:" e-map)
...