3

我目前正在尝试学习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)应该为真。

在实践中,MainMenufalse在控制台上,因为selected有值nil

4

2 回答 2

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])})

其余代码保持不变。

于 2016-01-07T16:04:06.397 回答
1

如您所见,在om.next中,所有查询都必须组合到根组件。根组件是props根据read函数在处理根查询时返回的内容分配的。

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

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

于 2016-01-21T04:39:17.830 回答