查询函数返回值为零在om.next
问题描述:
我目前正在努力学习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
)。
由于读取函数应该返回{:value :home}
(应用程序状态的值),因此(= selected :home)
应该为true。
实际上,MainMenu
在控制台上写入false
,因为selected
的值为nil
。
答
原来,在(om/add-root!)
上呈现的RootView
组件必须为所有应用程序提供查询。
在这种情况下,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])})
其余代码保持不变。
答
在om.next
中,正如您发现的那样,所有查询都必须组成根组件。根组件根据read
函数在处理根查询时返回的内容为其分配props
。
如果有任何子组件有查询,则该查询所请求的道具应作为第一个参数传递给子组件的工厂方法。这是你错过的第二件作品。
如果您在子组件中查询最终没有被父组件传回的内容,Om中目前没有任何警告或错误。所以如果你忘记传递道具,你最终会解构子组件中的钥匙的nil
值。