Om ref cursor 在更新时不是 re-rendering 组件

Om ref cursor not re-rendering components when updated

(ns ^:figwheel-always refs-test.core
(:require [om.core :as om :include-macros true]
          [om.dom :as dom :include-macros true]
          [sablono.core :as html :refer-macros [html]]))

(enable-console-print!)

(def app-state
  (atom {:items [{:text "cat"}
             {:text "dog"}
             {:text "bird"}]
     :selected-item {}}))

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

(defn
  selected-item-title
  [_ owner]
  (reify
    om/IRender
    (render [_]
      (html
        [:div
        (let [selected (om/observe owner (selected-item))]
          (if (empty? selected)
            [:h1 "Nothing selected"]
            [:h1 (:text selected)]))]))))

 (defn
  selected-item-button
  [item owner]
  (reify
     om/IRender
    (render [_]
      (html
       [:li
        [:button {:on-click
                  (fn []
                    (om/update! (om/root-cursor app-state) :selected-item item)                      ;; this doesn't update
                    ;;(om/update! (om/root-cursor app-state) :selected-item (merge item {:foo 1}))   ;; this does
                  )} (:text item)]]))))

(defn
  root
  [cursor owner]
  (reify
    om/IRender
    (render [_]
      (html
       [:div
        (om/build selected-item-title {})
        [:ul
         (om/build-all selected-item-button (:items cursor))]]))))


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

(https://www.refheap.com/108491)

(selected-item) 函数创建了一个 ref-cursor,它跟踪 app-state 中的 :selected-item 键。当您单击 selected-item-button 时,标题会更改以反映已放入地图中的新值。但是,这只有效一次。按不同的按钮不会导致标题再次 re-render,因此标题始终停留在您按下的第一个按钮的值上。

虽然,简单地添加一个 merge 和一个额外的关键字似乎可以让它工作......(与空地图合并也不起作用,试过!)

我对引用游标的理解有误吗?

所以,问题很简单。

(om/update! (om/root-cursor app-state) :selected-item item)

应该是

(om/update! (om/root-cursor app-state) :selected-item @item)

请注意该项目,因为它是一个游标,所以被取消引用。