3

这个问题最好用一个例子来解释:

;; 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在需要时使用块,但我不明白为什么我不得不将这个简单的示例包装在一个块中。

4

1 回答 1

1

它认为 will-mount 不是更新游标的好地方。使用 :fn 选项调用 om/build 将完成您想要实现的目标。

组件仅呈现一次,并带有更新的光标。

(om/build mycomponent data {:fn #(assoc % :text "Success !")})

https://github.com/swannodette/om/wiki/Documentation#build

于 2015-01-22T22:31:49.410 回答