【问题标题】:using core.async / ajax data in om component在 om 组件中使用 core.async / ajax 数据
【发布时间】:2015-01-14 07:29:27
【问题描述】:

我目前正在试验 om 并尝试加载外部数据以在组件中显示它。

我的详细组件:

(defn detail-component [app owner opts]
  (reify
    om/IInitState
    (init-state [_]
                (om/transact! app [:data] (fn [] "Test")))
    om/IWillMount
    (will-mount [_]
      (go (let [foo (<! (fetch-something 1))]
           (om/update! app #(assoc % :data foo))
           )))
    om/IRender
    (render [_]
      (dom/div nil
               (dom/h1 nil "Foo")
               (om/build another-component app)
               )
      ))
  )

fetch-something 正在从 API 检索数据)。

(defn another-component [{:keys [data]}]
  (om/component
    (.log js/console data)
    (dom/h2 nil "Another component goes here")
    (dom/h2 nil (data :description))
    )
  )

总而言之,detail-component 在挂载之前获取数据,将其附加到app 并构建another-componentanother-component 然后从该数据中取出描述并显示它。

但是在执行时,我在尝试访问描述时收到Uncaught TypeError: Cannot read property 'call' of null。这向我表明,在构建another-component 时,数据还不存在并且它失败了。

当数据可用时,我如何告诉 om 构建应用程序?还是我必须建立一些nil? 检查?

【问题讨论】:

    标签: reactjs clojurescript core.async om


    【解决方案1】:

    使用状态的工作示例:

    项目.clj

    (defproject asajax "0.0.1-SNAPSHOT"
      :description "FIXME: write description"
      :url "http://example.com/FIXME"
      :license {:name "Eclipse Public License - v 1.0"
                :url "http://www.eclipse.org/legal/epl-v10.html"
                :distribution :repo}
      :min-lein-version "2.3.4"
      :source-paths ["src/clj" "src/cljs"]
      :dependencies [[org.clojure/clojure "1.6.0"]
                     [org.clojure/clojurescript "0.0-2371"]
                     [org.clojure/core.async "0.1.267.0-0d7780-alpha"]
                     [om "0.7.3"]
                     [com.facebook/react "0.11.2"]]
      :plugins [[lein-cljsbuild "1.0.4-SNAPSHOT"]]
      :hooks [leiningen.cljsbuild]
      :cljsbuild
      {:builds {:asajax
                {:source-paths ["src/cljs"]
                 :compiler
                 {:output-to "dev-resources/public/js/asajax.js"
                  :optimizations :whitespace
                  :pretty-print true}}}})
    

    core.cljs

    (ns asajax.core
      (:require [om.core :as om :include-macros true]
                [om.dom :as dom :include-macros true]
                [cljs.core.async :as async])
      (:require-macros [cljs.core.async.macros :refer (go)]))
    
    (enable-console-print!)
    
    (def app-state (atom {}))
    
    (defn another-component [{:keys [data]}]
      (reify
        om/IRenderState
        (render-state [_ state]
          (dom/div nil
                   ;; (.log js/console data)
                   (dom/h2 nil "Another component goes here")
                   (dom/h2 nil (:description state))))))
    
    (defn fetch-something [x]
      (let [c (async/chan)]
        (go
          ;; pretend a blocking call
          ;; wait for 2 sec
          (<! (async/timeout 2000))
          (>! c {:data "Roast peach & Parma ham salad"
                 :description "This is a lovely light starter with fantastic sweet, salty and creamy flavours"}))
        c))
    
    (defn detail-component [app owner opts]
      (reify
        om/IInitState
        (init-state [_]
          {:data "Test"})
        om/IWillMount
        (will-mount [_]
          (go (let [foo (<! (fetch-something 1))]
                ;; (prn "GOT" foo)
                (om/set-state! owner foo))))
        om/IRenderState
        (render-state [_ state]
          (dom/div nil
                   (dom/h1 nil (:data state))
                   (om/build another-component app
                             {:state (om/get-state owner)})))))
    
    (om/root
     detail-component
     app-state
     {:target (. js/document (getElementById "app"))})
    

    更新2

    这是一个使用 sablono 而没有使用 set-state 的例子!

    添加到 project.clj

             [sablono "0.2.22"]
    

    完整的 core.cljs

    (ns asajax.core
      (:require [om.core :as om :include-macros true]
                [om.dom :as dom :include-macros true]
                [cljs.core.async :as async]
                [sablono.core :as html :refer-macros [html]])
      (:require-macros [cljs.core.async.macros :refer (go)]))
    
    (enable-console-print!)
    
    (def app-state (atom {:data "Initial"
                          :description "Loading..."}))
    
    (defn another-component [{:keys [description]}]
      (om/component
       (html
        [:.description
         [:h2 "Another component"]
         [:h2 description]])))
    
    (defn fetch-something [x]
      (let [c (async/chan)]
        (go
          ;; pretend a blocking call
          ;; wait for 2 sec
          (<! (async/timeout 2000))
          (>! c {:data "Roast peach & Parma ham salad"
                 :description "This is a lovely light starter with fantastic sweet, salty and creamy flavours"}))
        c))
    
    (defn detail-component [app owner opts]
      (reify
        om/IWillMount
        (will-mount [_]
          (go (let [foo (<! (fetch-something 1))]
                ;; (prn "GOT" foo)
                (om/update! app foo))))
        om/IRender
        (render [_]
          (html [:div
                 [:h1 (:data app)]
                 (om/build another-component app)
                 ]))))
    
    (om/root
     detail-component
     app-state
     {:target (. js/document (getElementById "app"))})
    

    【讨论】:

    • 很有趣,谢谢。我使用本指南作为参考,它没有这样做但仍然有效 - zaiste.net/2014/02/…。如果我在交易期间取消应用程序,请按照您的建议!并更新!,我收到Cannot deref cursor during render phase。如果我只在更新期间取消引用应用程序! (在 go 块内),我收到No protocol method ITransact defined for type cljs.core/PersistentArrayMap (...) :data "Test"
    • 是的,对不起。看来您忘记了 om/update 的光标!称呼。 github.com/swannodette/om/blob/master/src/om/core.cljs#L1155
    • 示例使用非常旧的 om "0.3.6",我认为是 om/update!从那以后改变了。
    • 感谢您的详细解释。我想我已经超越了自己,还不了解一些 om 核心概念。我的应用程序现在可以正确呈现,我是一个快乐的开发者。 (update! 在 go 块内仍然不适合我(Cannot read property (...) of null,但 transact! 可以。)
    猜你喜欢
    • 2017-12-01
    • 2016-03-26
    • 2014-08-18
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2022-10-25
    • 1970-01-01
    相关资源
    最近更新 更多