这个问题最好用一个例子来解释:
;; create a basic om app.
lein new mies-om om-tut
lein cljsbuild auto.
然后粘贴以下代码(在core.cljs
)
(ns om-tut.core
(:require [om.core :as om :include-macros true]
[om.dom :as dom :include-macros true]))
(def app-state (atom {:text "Hello world!"}))
(om/root
(fn [app owner]
(reify
om/IWillMount
(will-mount [_]
(om/update! app :text "Success!!!"))
om/IRender
(render [_]
(dom/div nil (app :text ))
)))
app-state
{:target (. js/document (getElementById "app"))})
will-mount
中的代码实际上正在执行,如果你放入println
函数,那么你就会看到它。不清楚的是为什么渲染循环只被调用一次。另一方面,如果您将om/update!
包裹在go
块中,那么它会按预期工作:
;; add [org.clojure/core.async "0.1.346.0-17112a-alpha"] to your deps in project.clj
(ns om-tut.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [om.core :as om :include-macros true]
[cljs.core.async :refer [put! chan <! to-chan close!]]
[om.dom :as dom :include-macros true]))
(def app-state (atom {:text "Hello world!"}))
(om/root
(fn [app owner]
(reify
om/IWillMount
(will-mount [_]
(go
(om/update! app :text "Success!!")))
om/IRender
(render [_]
(dom/div nil (app :text )))))
app-state
{:target (. js/document (getElementById "app"))})
问题是:为什么will-mount
不会触发新的渲染循环,因为我更新了应用状态?我喜欢在需要时使用go
块,但我不明白为什么我被迫在一个块中包装这个简单的例子。
答案 0 :(得分:1)
它认为will-mount不是更新游标的好地方。 使用:fn选项调用om / build将执行您尝试实现的操作。
使用更新的光标,只渲染一次组件。
(om/build mycomponent data {:fn #(assoc % :text "Success !")})