Om Next子查询对子组件道具没有影响

时间:2016-11-01 06:35:17

标签: clojurescript om

阅读Om Next教程页面Components, Identity & Normalization,我认为子组件(Person组件)中的子查询用于填充Person的道具。但是从

更改查询
'[:name :points :age]

'[]

不会破坏应用。你能帮我理解解析器如何从这些组件/查询树中调用读取方法。

页面中的整个代码如下。

(def init-data
  {:list/one [{:name "John" :points 0}
              {:name "Mary" :points 0}
              {:name "Bob"  :points 0}]
   :list/two [{:name "Mary" :points 0 :age 27}
              {:name "Gwen" :points 0}
              {:name "Jeff" :points 0}]})

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

(defmulti read om/dispatch)

(defn get-people [state key]
  (let [st @state]
    (into [] (map #(get-in st %)) (get st key))))

(defmethod read :list/one
  [{:keys [state] :as env} key params]
  {:value (get-people state key)})

(defmethod read :list/two
  [{:keys [state] :as env} key params]
  {:value (get-people state key)})

(defmulti mutate om/dispatch)

(defmethod mutate 'points/increment
  [{:keys [state]} _ {:keys [name]}]
  {:action
   (fn []
     (swap! state update-in
            [:person/by-name name :points]
            inc))})

(defmethod mutate 'points/decrement
  [{:keys [state]} _ {:keys [name]}]
  {:action
   (fn []
     (swap! state update-in
            [:person/by-name name :points]
            #(let [n (dec %)] (if (neg? n) 0 n))))})

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

(defui Person
  static om/Ident
  (ident [this {:keys [name]}]
    [:person/by-name name])
  static om/IQuery
  (query [this]
    '[])
  Object
  (render [this]
    (println "Render Person" (-> this om/props :name))
    (let [{:keys [points name age] :as props} (om/props this)]
      (dom/li nil
              (dom/label nil (str name ", points: " points ", age: " age))
              (dom/button
                #js {:onClick
                     (fn [e]
                       (om/transact! this
                                     `[(points/increment ~props)]))}
                "+")
              (dom/button
                #js {:onClick
                     (fn [e]
                       (om/transact! this
                                     `[(points/decrement ~props)]))}
                "-")))))

(def person (om/factory Person {:keyfn :name}))

(defui ListView
  Object
  (render [this]
    (println "Render ListView" (-> this om/path first))
    (let [list (om/props this)]
      (apply dom/ul nil
             (map person list)))))

(def list-view (om/factory ListView))

(defui RootView
  static om/IQuery
  (query [this]
    (let [subquery (om/get-query Person)]
      `[{:list/one ~subquery} {:list/two ~subquery}]))
  Object
  (render [this]
    (println "Render RootView")
    (let [{:keys [list/one list/two]} (om/props this)]
      (apply dom/div nil
             [(dom/h2 nil "List A")
              (list-view one)
              (dom/h2 nil "List B")
              (list-view two)]))))

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

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

1 个答案:

答案 0 :(得分:0)

从阅读this开始,我知道解析器只处理顶级查询。并且您有责任通过访问(:query env)来提供您自己的子查询读取。