在Om Next中解析外键

时间:2017-08-30 08:32:15

标签: clojurescript om om-next

我试图理解Om Next中的规范化,身份和查询概念。每次我想我拥有它,我都会遇到一种似乎让我感到困惑的新情况。

我有一个返回以下数据的遥控器:

{:users [
  {:id 1,
   :email "foo@example.com",
   :role 1},
  {:id 3,
   :email "bar@floyhamilton.nl",
   :role 1},
  {:id 4,
   :email "baz@example.com",
   :role 1},
  {:id 6,
   :email "nom@example.com",
   :role 1}}]
  :roles [
    {:id 1, :name "admin"}]}

我已经构建了这样的组件:

(defui Root
  static om/IQuery
  (query [this]
     `[{:users ~(om/get-query User)}
       {:roles ~(om/get-query Role)}]))

(defui Role
  static om/Ident
  (ident [this {:keys [id]}]
         [:role/by-id id])
  static om/IQuery
  (query [this]
         [:id :name]))

(defui User
  static om/Ident
  (ident [this {:keys [id]}]
         [:user/by-id id])
  static om/IQuery
  (query [this]
         [:id :email :role]))

这会导致协调程序对我的数据进行规范化,如下所示:

{:users
 [[:user/by-id 1] [:user/by-id 3] [:user/by-id 4] [:user/by-id 6]],
 :roles [[:role/by-id 1]],
 :user/by-id
 {1
  {:id 1,
   :email "foo@example.com",
   :role 1},
  3
  {:id 3,
   :email "bar@floyhamilton.nl",
   :role 1},
  4
  {:id 4,
   :email "baz@example.com",
   :role 1},
  6
  {:id 6,
   :email "nom@example.com",
   :role 1}},
 :role/by-id {1 {:id 1, :name "admin"}}}

现在,关于我的问题。我想在组件中访问用户的角色名称。我可以在User组件的render函数中执行类似(get-in @app-state [:role/by-id role :name])的操作,但这看起来不像是惯用的事情。

"Thinking with links"上的Om Next文档似乎提到了我的解决方案:idents。我尝试在用户查询中使用此功能(如[:id :email [:role/by-id 1]]),这样可行!但是,我似乎无法将实际角色ID插入到身份证中!我已经尝试了非常复杂的查询参数,将其插入到缩进中,但这一切看起来都非常糟糕。

这似乎是一个非常普遍的情况,应该有一个体面的解决方案,但我似乎无法得到它!

*编辑添加了根组件

1 个答案:

答案 0 :(得分:1)

User的查询语法应该是这样的:

[:id :email {:user-role (om/get-query Role)}]

然后用户的表状态可能是:

{:id 6,
 :email "nom@example.com",
 :user-role [:role/by-id 1]}

如果您在问题中显示defui,尤其是Root,则会有所帮助。 Om.Next的一件事是所有连接都必须在Root组件上完成,以便使应用程序状态正确标准化。