秘书路由,在om.next中的Ident查询

时间:2017-02-10 06:28:49

标签: clojurescript om om.next secretary

我将在这个问题的前言中说我在Clojure / Script方面仍然是一个新手,所以除了非常尖锐的问题,我将提出关于风格的任何一般性反馈,我将非常感激使用。

我用om.next构建了一个非常简单的应用程序。对于客户端路由,我决定使用Secretary。我的应用程序显示项目列表,目的是当您单击其中一个项目时,您可以查看详细信息。目前的实现是通过锚标记上的简单href(例如,href可能看起来像/items/1,其中1id)。部分原因是您应该能够直接导航到详细信息URL以查看相同的视图。就像这听起来一样简单,我不能为我的生活让这个按照需要工作。

首先,让我们看看协调程序的显着配置(为简洁起见,我已经删除了整个组件render的实现细节)......

(def init-data {:items [{:id 1
                         :title "stack overflow"
                         :description "hello, world."
                         :photos []}
                        {:id 2
                         :title "foo"
                         :description "bar"
                         :photos []}]})

(defui ListItem
  static om/Ident
  (ident [this {:keys [id]}]
    [:items/by-id id])
  static om/IQuery
  (query [this]
    [:id :title :description :photos]))

(defui Items
  static om/IQuery
  (query [this]
    [{:items (om/get-query ListItem)}]))

(defmulti read om/dispatch)

(defmethod read :items
  [{:keys [state query] :as env} key _]
  (let [st @state]
    {:value (om/db->tree query (get st key) st)}))

(def app-state (atom (om/tree->db Items init-data true)))

(def reconciler
  (om/reconciler {:parser (om/parser {:read read})
                  :state app-state}))

精明的人会看到我正在努力think with links,这似乎正如我所期望的那样起作用。当我添加这个组件,并尝试在秘书路线后面使用它时,一切都崩溃了......

; I tried other approaches, they failed too
(defui Item
  static om/IQueryParams
  (params [this]
    {:id :not-found})
  static om/IQuery
  (query [this]
    '[[:items/by-id ?id]]))

(defn render-component [component]
  (let [app (gdom/getElement "app")]
    (doto reconciler
      (om/remove-root! app)
      (om/add-root! component app)))))

(defroute item-path "/items/:id" [id]
  (let [component Item]
    ; this is already less than ideal, as we know the id
    ; before the first render of the component
    (render-component component)
    (om/set-query! (om/class->any reconciler component)
                   {:id (js/parseInt id)})))

我的Item组件的实例未在props中收到查询中指定的正确状态(它接收整个app-state)。最令我困惑的是,如果我在REPL中手动对app-state执行相同的查询,我会得到正确的数据集......

(get-in @app-state [:items/by-id 1])
; {:id 1, :title "stack overflow", :description "hello, world.", :photos []}

到目前为止,对我来说唯一有用的是绕过协调程序(自己创建组件实例),将app-state的查询值作为道具传递。但这意味着我不能通过调和来改变状态,这是一个新的可怕的皱纹,而不是一个混乱,不整洁的难题。

我在这里缺少什么?虽然我有很多想法,但我最怀疑的是通过app-state初始化om/tree->db

0 个答案:

没有答案