查询函数在om.next中将值返回为nil

时间:2016-01-07 02:40:21

标签: clojure clojurescript om om.next

我目前正在尝试学习 om.next

这是我的代码:

(ns hlearn.core
  (:require [goog.dom :as gdom]
            [om.next :as om :refer-macros [defui]]
            [om.dom :as dom]
            [sablono.core :as html :refer-macros [html]]))

(enable-console-print!)

(def app-data
  (atom {:user ""
         :main-menu {:selected :home}}))

;; -------------------------------------------------------------------------
;; Parsing

(defmulti read om/dispatch)

(defmethod read :selected
  [{:keys [state]} _ _]
  {:value (get-in @state [:main-menu :selected])})

;; -------------------------------------------------------------------------
;; Components

(defui MainMenu
  static om/IQuery
  (query [this]
         [:selected])
  Object
  (render [this]
          (let [{:keys [selected]} (om/props this)]
            (println (= selected :home)))))

(def main-menu (om/factory MainMenu))

(defui RootView
  Object
  (render [this]
    (println "Render RootView")
    (main-menu)))

(def reconciler
  (om/reconciler
   {:state  app-data
    :parser (om/parser {:read read})}))

(om/add-root! reconciler
  RootView (gdom/getElement "app"))

我的目标是组件MainMenu必须在控制台上编写true(目前正在编写false)。

由于read函数应返回{:value :home}(app-state的值),因此(= selected :home)应为true。

实际上,MainMenu在控制台上写false,因为selected的值为nil

2 个答案:

答案 0 :(得分:2)

事实证明,RootView上呈现的(om/add-root!)组件必须为所有应用程序提供查询。

在这种情况下,RootView也必须提供查询,并将selected密钥传递给MainMenu组件。

(def app-data
  (atom {:user ""
         :menu {:selected :home}}))

(defui RootView
  static om/IQuery
  (query [this]
    `[{:menu (om/get-query MainMenu)}])
  Object
  (render [this]
    (let [{:keys [menu]} (om/props this)]
      (println "Render RootView")
      (main-menu menu))))

此外,阅读器功能会调度:menu键,而不是:selected键。

(defmethod read :menu
  [{:keys [state]} _ _]
  {:value (get-in @state [:menu])})

其余代码保持不变。

答案 1 :(得分:1)

om.next中,正如您所发现的,所有查询都必须组成根组件。根据{{​​1}}函数在处理根查询时返回的内容,为根组件分配其props

如果任何子组件有查询,则该查询请求的props应该作为子组件的工厂方法的第一个参数传递。这是你失踪的第二件。

如果您查询子组件中最终未被其父组件传递的内容,则Om中目前没有任何警告或错误。因此,如果您忘记传递道具,最终会为子组件中的键解构read值。