Om Next read multi-fn 未在二级连接中调用,查询 AST 未完全解析,因此组件仅接收标识
Om Next read multi-fn not being called in second level join, Query AST not parsed fully, therefore component only receiving idents
我无法让二级连接正常工作。为了简洁起见,我在这里省略了一些内容。
我的根组件是:
(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 的读取函数并且 returns 它是数据,尽管 :body、:media 和 :start-date 的所有第二个连接都不是。
我的读取函数如下,第二个是没有调用的。我省略了 :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}]}]}]}
我不明白为什么解析器或其他东西(?)在第二次连接时停止?就我有限的理解而言,至少应该调用 :body 上的 multi-method?
所以我遇到的问题是我认为的理解之一,Om Slack 频道中的 António Monteiro 建议我使用 db->tree
函数。在 :list/events
多方法中使用它让我们 return 整个去规范化数据树。
您必须自己从读取内部进行递归,即在被检查的键内的查询上调用解析器。 db->tree
为您做这件事。事实上,每个 read
调用 db->tree
并因此看起来几乎相同的情况并不少见。事实上,正因为如此,Untangled 完全取消了这些阅读。在这种情况下,您真的不必自己进行递归!
这里没有递归:
(into [] (map #(get-in st %)) (get st key))
key
上的任何 get
是 refs 部分 的 default db 格式化 数据(应用程序数据)。因此,(get st key)
将返回一系列标识。任何 get-in
都是应用程序数据的表部分,因此 returns 真实数据值。 (map #(get-in st %))
是为每个身份执行此操作的转换器。但是数据的 表部分 是一个递归数据结构 - 必须是因为没有重复 - 所以任何不是 'leaf' 数据的数据都由一个标识表示。所以这就是您要返回的内容 - 任何深一层的东西,否则就是标识。
如果不了解默认数据库格式 - refs
和 tables
部分,这个答案几乎毫无意义。到目前为止我找到的最好的解释是 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
是一个键,其中关联的值是一个标识向量。 (get st :list/people)
会给你这个向量。此映射是 st
.
的 refs 部分
我无法让二级连接正常工作。为了简洁起见,我在这里省略了一些内容。
我的根组件是:
(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 的读取函数并且 returns 它是数据,尽管 :body、:media 和 :start-date 的所有第二个连接都不是。
我的读取函数如下,第二个是没有调用的。我省略了 :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}]}]}]}
我不明白为什么解析器或其他东西(?)在第二次连接时停止?就我有限的理解而言,至少应该调用 :body 上的 multi-method?
所以我遇到的问题是我认为的理解之一,Om Slack 频道中的 António Monteiro 建议我使用 db->tree
函数。在 :list/events
多方法中使用它让我们 return 整个去规范化数据树。
您必须自己从读取内部进行递归,即在被检查的键内的查询上调用解析器。 db->tree
为您做这件事。事实上,每个 read
调用 db->tree
并因此看起来几乎相同的情况并不少见。事实上,正因为如此,Untangled 完全取消了这些阅读。在这种情况下,您真的不必自己进行递归!
这里没有递归:
(into [] (map #(get-in st %)) (get st key))
key
上的任何 get
是 refs 部分 的 default db 格式化 数据(应用程序数据)。因此,(get st key)
将返回一系列标识。任何 get-in
都是应用程序数据的表部分,因此 returns 真实数据值。 (map #(get-in st %))
是为每个身份执行此操作的转换器。但是数据的 表部分 是一个递归数据结构 - 必须是因为没有重复 - 所以任何不是 'leaf' 数据的数据都由一个标识表示。所以这就是您要返回的内容 - 任何深一层的东西,否则就是标识。
如果不了解默认数据库格式 - refs
和 tables
部分,这个答案几乎毫无意义。到目前为止我找到的最好的解释是 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
是一个键,其中关联的值是一个标识向量。 (get st :list/people)
会给你这个向量。此映射是 st
.