Om Next读取未在二级连接中调用multi-fn,查询AST未完全解析,因此组件仅接收ident

时间:2016-03-27 11:08:28

标签: clojurescript om

我无法让第二级联接正常工作。为了简单起见,我在这里省略了一些事情。

我的根组件是:

(defui RootView
  static om/IQuery
  (query [this]
    `[{:list/events ~(om/get-query Event)}])
  Object
  (render [this]
    (let [{:keys [list/events]} (om/props this)]
      (events/event-list events))))

我的查询组成正确,初始数据正确规范化。我不会显示标准化数据,而且总查询还有更多。

(prn (om/get-query RootView)) =>

[{:list/events
  [:id
   {:body [:id :text :headline]}
   {:media [:id :url :caption :credit]}
   {:start-date [:id :year :month :day]}]}]

如果我通过解析器运行包含连接的查询,我得到:

(prn (parser {:state (atom norm-data)}
       '[{:list/events
          [:id
           {:body [:id :text :headline]}
           {:media [:id :url :caption :credit]}
           {:start-date [:id :year :month :day]}]}])) =>

{:list/events
 [{:id 1,
   :media [:media/by-id 1],
   :start-date [:start-date/by-id 1],
   :body [:body/by-id 1]}
  {:id 17,
   :media [:media/by-id 17],
   :start-date [:start-date/by-id 17],
   :body [:body/by-id 17]}]}

因此调用:list / events的read函数并返回它的数据,尽管所有第二个连接:body,:media和:start-date都没有。

我的阅读功能如下,第二个是未调用的功能。我遗漏了多方法:媒体和:开始日期,它们也没有被调用。我不确定这是什么症状。

(defmulti read om/dispatch)

(defmethod read :list/events
  [{:keys [state] :as env} key params]
  (let [st @state]
    {:value (into [] (map #(get-in st %)) (get st key))}))

(defmethod read :body
  [{:keys [state query]} key _]
  (println "This is never printed")
  {:value :doesnt-matter})

在AST中正确识别连接(因此我假设查询语法是正确的)并且调度键与多方法的匹配。

(prn (om/query->ast (om/get-query RootView))) =>

{:type :root,
 :children
 [{:type :join,
   :dispatch-key :list/events,
   :key :list/events,
   :query
   [:id
    {:body [:id :text :headline]}
    {:media [:id :url :caption :credit]}
    {:start-date [:id :year :month :day]}],
   :component timeline.components.events/Event,
   :children
   [{:type :prop, :dispatch-key :id, :key :id}
    {:type :join,
     :dispatch-key :body,
     :key :body,
     :query [:id :text :headline],
     :component timeline.components.events/EventBody,
     :children
     [{:type :prop, :dispatch-key :id, :key :id}
      {:type :prop, :dispatch-key :text, :key :text}
      {:type :prop, :dispatch-key :headline, :key :headline}]}]}]}

我无法理解为什么解析器或其他东西(?)在第二次连接时停止?至于我有限的理解,至少应该调用身体上的多方法吗?

2 个答案:

答案 0 :(得分:1)

所以我遇到的问题是理解我认为,Om Slack频道中的AntónioMonteiro建议我使用db->tree函数。在:list/events多方法中使用它,让它返回整个非规范化数据树。

答案 1 :(得分:0)

您必须自己从读取中进行递归,即在正在检查的键内的查询上调用解析器。 db->tree为您完成此操作。事实上,每个read调用db->tree并不常见,因此看起来几乎相同。事实上,由于这个Untangled完全取消了这些读取。在这种情况下,你真的不需要自己做递归!

这里没有递归:

(into [] (map #(get-in st %)) (get st key)) 

get上的任何key都是默认数据库格式数据(应用数据)的引用部分。所以这里将由(get st key)返回一系列的标识。任何get-in都是app数据的表部分,因此返回实际数据值。 (map #(get-in st %))是为每个身份执行此操作的换能器。但是数据的表部分是一个递归数据结构 - 必须是缺乏重复 - 所以任何不是'叶'数据的数据都由一个ident表示。所以这就是你要回来的东西 - 任何一个层次的东西,其他任何东西。

如果不了解默认数据库格式 - refstables部分,这个答案将毫无意义。到目前为止,我发现的最佳解释是here

此数据(st)采用默认数据库格式

{ :list/people [[:people/by-id 1] [:people/by-id 2] ... ]
  :people/by-id { 1 { :db/id 1 :person/name "Joe" :person/mate [:people/by-id 2]}
                  2 { :db/id 2 :person/name "Sally" :person/mate [:people/by-id 1]}}}

无论您在何处看到by-id,都可以将密钥放在 tables mapentry中。正如您所看到的,(get-in st [:people/by-id 1])结构将为您检索一个真实数据的地图,当然只有一个深度。

此处:list/people是一个关键值,其中关联值是idents的向量。 (get st :list/people)将为您提供此向量。此mapentry是st refs 部分。