Секретарь маршрутизации, Ident Query в om.next

Я предрежу этот вопрос, сказав, что я все еще очень новичок, когда дело доходит до Clojure/Script, поэтому, помимо очень острого вопроса, я буду давать какие-либо общие отзывы о стиле, использование будет с благодарностью.

Я создавал очень простое приложение с помощью om.next. Для маршрутизации на стороне клиента я решил использовать секретарь. Мое приложение отображает список элементов, и предполагается, что при нажатии на один из этих элементов вы можете просмотреть детали. Реализация в настоящее время осуществляется с помощью простого href на теге привязки (например, href может выглядеть как /items/1, где 1 это id). Это отчасти потому, что вы должны иметь возможность перейти к 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}))

Проницательный увидит, что я пытаюсь мыслить ссылками, и это, похоже, работает, как я и ожидал. Когда я добавляю этот компонент и пытаюсь использовать его за секретным маршрутом, все рушится...

; 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). Что меня больше всего удивляет, так это то, что если я выполню тот же запрос app-state вручную в REPL я получаю правильный набор данных обратно...

(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 ответов

Другие вопросы по тегам