次のようなコンポーネントとサブコンポーネントを使用して、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/transact! しかし、それらはカーソルを取り、メニューアイテムビューにある唯一のカーソルは、完全なアプリ状態ではなく、現在のメニューアイテムです。そのため、:location にアクセスできません。
これはどのように処理されますか?
可能であれば、当面は core.async とチャネルを避けたいと思います。