clojurescript - Om 应用程序状态和应用程序结构

标签 clojurescript om

我在 Om 中显示一个菜单,使用这样的组件和子组件:

(def app-state (atom {:location ""
                      :menuitems [["Pages" "/pages/"]
                                  ["Images" "/images/"]]}))

(defn menu-item-view [parent-cursor item owner]
  (reify
    om/IRender
    (render [this]
      (dom/li #js {:className (if (= (:location @app-state) (last item)) "active" "inactive")} 
        (dom/a #js 
               {:onClick (fn [_] (swap! app-state assoc :location (last @item)))} 
               (first item))))))

(defn menu-view [app owner]
  (reify
    om/IRender
    (render [this]
      (dom/li #js {:className "has-dropdown not-click"}
        (dom/a nil "Menu")
        (apply dom/ul #js {:className "dropdown"}
          (om/build-all (partial menu-item-view app) 
                        (:menuitems app)))))))

(om/root menu-view app-state
  {:target (. js/document (getElementById "menu"))})

我的问题是如何更新 (@app-state :location) 并正确重新呈现菜单?

上面代码中的更新:
(swap! app-state assoc :location (last @item))

确实有效,但树没有正确更新。

我怀疑我需要使用 om/update!或 om/交易!但他们需要一个光标,我在菜单项 View 中唯一的光标是当前菜单项,而不是完整的应用程序状态。所以我无法访问:位置。

这是如何处理的?

如果可能的话,我宁愿暂时避免 core.async 和 channels。

最佳答案

现在我们有了 reference cursors你可能会做这样的事情:

(def app-state (atom {:location ""
                      :menuitems [["Pages" "/pages/"]
                                  ["Images" "/images/"]]}))

(defn location []
  (om/ref-cursor (:location (om/root-cursor app-state))))

(defn menu-item-view [item owner]
  (reify
    om/IRender
    (render [this]
      (let [x (location)]
        (dom/li #js {:className (if (= x (last item)) "active" "inactive")}
                (dom/a #js
                       {:onClick (fn [_] (om/update! x (last @item)))}
                       (first item)))))))

(defn menu-view [app owner]
  (reify
    om/IRender
    (render [this]
      (dom/li #js {:className "has-dropdown not-click"}
              (dom/a nil "Menu")
              (apply dom/ul #js {:className "dropdown"}
                     (om/build-all menu-item-view (:menuitems app)))))))

(om/root menu-view app-state
  {:target (. js/document (getElementById "menu"))})

这只是一个想法 - 我还没有真正测试过它。

关于clojurescript - Om 应用程序状态和应用程序结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26354662/

相关文章:

namespaces - ClojureScript 评估。如何使用调用代码中包含的库

clojure - Om Next 的 query->ast 和 ast->query 函数

css - om 中的动态样式表

clojure - clojure 中主机互操作点宏是如何实现的

unit-testing - 通过模拟请求使用异步 api 调用测试组件

clojure - 如何在 clojure 中访问 c​​ore.cljs 中的 db.clj 方法

clojure - 为组件数据中缺少的键设置初始状态

syntax - Clojure — 英镑符号的含义?`

clojure - Clojure 中的 def 和 defonce 有什么区别?

clojure - 修改参数作为多方法的一部分