Функция запроса, возвращающая значение как ноль в 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) должно быть правдой.

На практике, MainMenu пишет false на консоли, потому что selected имеет значение nil,

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

Остальная часть кода остается прежней.

В om.nextвсе запросы должны составлять корневой компонент, как вы обнаружили. Корневому компоненту назначается его props на основании чего read Функция возвращает, когда обрабатывает корневой запрос.

Если какой-либо субкомпонент имеет запрос, реквизиты, запрошенные этим запросом, должны быть переданы в качестве первого аргумента фабричного метода субкомпонента. Это был второй кусок, который вы пропустили.

В настоящее время в Om нет предупреждений или ошибок, если вы запрашиваете что-то в подкомпоненте, которое в конечном итоге не передается его родителем. Таким образом, вы в конечном итоге разрушает nil значение ключа в подкомпоненте, если вы забыли передать реквизиты.

Другие вопросы по тегам