了解 Om 查询和 UI 组合
Understanding Om queries and UI composition
我一直在努力解决问题。假设我想要一个 Root
组件,上面有多个 table-views。
official tutorial suggests - 一种方法是让 table-view 组件不带查询。
然后你可以通过 props 传递它需要使用的任何数据,这工作得很好。
但这是非常简单的情况。在非平凡的应用程序中,您可能希望 TableView
带有查询,因为在 UI 树下您可能有一些复杂的 UI 组件结构 - table - 页眉、页脚、行、单元格等。
现在 this tutorial 建议使用查询方法:
但这仍然是一个稍微简化的例子。那么假设我有:
(defmethod read :numbers/odd [_ _ _]
{:value (filter odd? (range 50))})
(defmethod read :numbers/even [_ _ _]
{:value (filter even? (range 50))})
在真实的应用程序中,当然数据会来自后端,Om 会将其粘贴到状态原子中(像往常一样)
现在我需要一个 TableView
组件 和一个查询 可以呈现其中任何一个(或本例中的任何序列)。所以你看到 我必须以某种方式告诉 TableView
组件使用位于状态原子 中其他地方的数据。 TableView
的查询应该是 "dynamic",所以我可以使用多个 TableViews
渲染不同的数据。
假设我们有这样的根:
(defui Root
(query [_] [{:table/odd ,,,} {:table/even ,,,}])
(render
[this]
(let [{:keys [table/odd table/even]}]
(html [:div
[:div.odds (ui-table-view odd)]
[:div.evens (ui-table-view even)]]))))
为了啤酒我省略了Om.Next接口
现在我有几个问题:
Root
的查询应该是什么样的?
- 我是否应该在
TableView
中进行参数化查询(我可能会在其中指示状态原子中数据的键)?或者我还能如何告诉一个 TableView
使用 :numbers/odd
而另一个使用 :numbers/even
?
- 如果我在
TableView
中使用参数化查询,那么如何将参数从 Root
传递到 TableView
?
- 也许我应该通过计算属性将数据或 link 传递给 TableView 的数据?
- 我将如何使用
om/get-query
(如果子查询被参数化)?
- 读取方法会是什么样子?我需要在
read
的原子中 "move things around" 吗?听起来不是个好主意
谁能给我举个例子。非常感谢!
这就是我想出的:
为每个 table 存储一个与其关联的数据键,然后在读取阶段获取该数据并关联到表示 table:
的映射
所以如果我们有几个 tables(奇数和偶数):
{:app/tables
[{:id 0
:title "Odd numbers"
:data-key :data/odds}
{:id 1
:title "Even numbers"
:data-key :data/evens}]}
这个读取方法看起来像:
(defmethod parsing/read :app/tables
[{:keys [state parser] :as env} k _]
(let [ts (get @state k)
merge-table-data' (fn [{:keys [data-key] :as t}]
(assoc t :table/data
(->> data-key
vector
(parser env)
vals
flatten)))]
{:value (map merge-table-data' ts)}))
这种方法有一个很大的缺点 - 它会尝试解析所有 table 的所有数据,所以我需要找到一种方法来改进它 - 我希望能够有选择地指定 tables 获取数据。
整个解决方案的片段是 here:
upd: 我做了一个改进版本(在gist中添加了一个文件)。在该示例中,现在您可以指定数据键,因此它只会加载指定的片段
upd2: 显然这种方法以某种方式打破了突变。这个想法是正确的 - 需要利用 Om.Next 的规范化机制。我稍后会尝试更新要点。
我一直在努力解决问题。假设我想要一个 Root
组件,上面有多个 table-views。
official tutorial suggests - 一种方法是让 table-view 组件不带查询。 然后你可以通过 props 传递它需要使用的任何数据,这工作得很好。
但这是非常简单的情况。在非平凡的应用程序中,您可能希望 TableView
带有查询,因为在 UI 树下您可能有一些复杂的 UI 组件结构 - table - 页眉、页脚、行、单元格等。
现在 this tutorial 建议使用查询方法:
但这仍然是一个稍微简化的例子。那么假设我有:
(defmethod read :numbers/odd [_ _ _]
{:value (filter odd? (range 50))})
(defmethod read :numbers/even [_ _ _]
{:value (filter even? (range 50))})
在真实的应用程序中,当然数据会来自后端,Om 会将其粘贴到状态原子中(像往常一样)
现在我需要一个 TableView
组件 和一个查询 可以呈现其中任何一个(或本例中的任何序列)。所以你看到 我必须以某种方式告诉 TableView
组件使用位于状态原子 中其他地方的数据。 TableView
的查询应该是 "dynamic",所以我可以使用多个 TableViews
渲染不同的数据。
假设我们有这样的根:
(defui Root
(query [_] [{:table/odd ,,,} {:table/even ,,,}])
(render
[this]
(let [{:keys [table/odd table/even]}]
(html [:div
[:div.odds (ui-table-view odd)]
[:div.evens (ui-table-view even)]]))))
为了啤酒我省略了Om.Next接口
现在我有几个问题:
Root
的查询应该是什么样的?- 我是否应该在
TableView
中进行参数化查询(我可能会在其中指示状态原子中数据的键)?或者我还能如何告诉一个TableView
使用:numbers/odd
而另一个使用:numbers/even
? - 如果我在
TableView
中使用参数化查询,那么如何将参数从Root
传递到TableView
? - 也许我应该通过计算属性将数据或 link 传递给 TableView 的数据?
- 我将如何使用
om/get-query
(如果子查询被参数化)? - 读取方法会是什么样子?我需要在
read
的原子中 "move things around" 吗?听起来不是个好主意
谁能给我举个例子。非常感谢!
这就是我想出的:
为每个 table 存储一个与其关联的数据键,然后在读取阶段获取该数据并关联到表示 table:
的映射所以如果我们有几个 tables(奇数和偶数):
{:app/tables
[{:id 0
:title "Odd numbers"
:data-key :data/odds}
{:id 1
:title "Even numbers"
:data-key :data/evens}]}
这个读取方法看起来像:
(defmethod parsing/read :app/tables
[{:keys [state parser] :as env} k _]
(let [ts (get @state k)
merge-table-data' (fn [{:keys [data-key] :as t}]
(assoc t :table/data
(->> data-key
vector
(parser env)
vals
flatten)))]
{:value (map merge-table-data' ts)}))
这种方法有一个很大的缺点 - 它会尝试解析所有 table 的所有数据,所以我需要找到一种方法来改进它 - 我希望能够有选择地指定 tables 获取数据。
整个解决方案的片段是 here:
upd: 我做了一个改进版本(在gist中添加了一个文件)。在该示例中,现在您可以指定数据键,因此它只会加载指定的片段
upd2: 显然这种方法以某种方式打破了突变。这个想法是正确的 - 需要利用 Om.Next 的规范化机制。我稍后会尝试更新要点。