了解 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接口

现在我有几个问题:

谁能给我举个例子。非常感谢!

这就是我想出的:

为每个 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 的规范化机制。我稍后会尝试更新要点。