了解Om查询和UI组合

时间:2016-12-23 05:33:29

标签: reactjs clojure clojurescript om-next

我一直试图绕过查询。假设我想要一个包含多个表视图的Root组件。

official tutorial suggests - 一种方法是拥有一个没有查询的表视图组件。 然后你可以通过道具传递它需要使用的任何数据,这样就可以了。

但这很简单。在非平凡的应用程序中,您可能希望TableView包含查询,因为在UI树下您可能有一些复杂的组件UI结构 - 表头,页脚,行,单元格等。 现在this tutorial建议使用查询方法:

然而这仍然是一些简化的例子。所以,假设我有:

(defmethod read :numbers/odd [_ _ _]
  {:value (filter odd? (range 50))})

(defmethod read :numbers/even [_ _ _]
  {:value (filter even? (range 50))})

在实际应用程序当然数据将来自后端,Om会将其粘贴到状态原子(像往常一样)

现在我需要一个带有查询的TableView组件,它可以呈现这些中的任何一个(或者在这种情况下是任何序列)。所以你看到我必须以某种方式告诉TableView组件使用位于state atom 其他地方的数据。 TableView的查询应该是“动态的”,因此我可以使用多个TableViews呈现不同的数据。

假设我们对Root有这样的东西:

(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)]]))))

for brewity我省略了Om.Next接口

现在我有几个问题:

  • Root的查询应该如何?
  • 我是否应该在TableView 中进行参数化查询(我可能会指出状态原子中数据的关键字)?或者我怎么告诉一个TableView使用:numbers/odd而另一个:numbers/even
  • 如果我在TableView中使用参数化查询,那么如何将Root中的参数传递给TableView
  • 也许我应该通过计算道具传递数据或链接到TableView的数据?
  • 我如何使用om/get-query(如果子查询是参数化的)?
  • 阅读方法如何?我是否需要在read的原子中“移动”?听起来不是一个好主意

有人可以给我看一些例子。非常感谢!。

1 个答案:

答案 0 :(得分:0)

所以这就是我提出来的:

对于每个表存储与其关联的数据键,然后在读取阶段获取该数据并关联到表示该表的映射:

因此,如果我们有几个表(奇数和偶数):

    {: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)}))

这种方法有一个很大的缺点 - 它会尝试解析所有表的所有数据,所以我需要找到一种方法来改进它 - 我希望能够有选择地指定表来获取数据。

整个解决方案的代码段为here

upd :我做了一个改进的版本(在gist中添加了一个文件)。在该示例中,您现在可以指定数据键,因此它只会加载指定的部分

upd2:显然这种方法会以某种方式破坏突变。这个想法是正确的 - 需要使用Om.Next的规范化机制。我稍后会尝试更新要点。