Om ref cursor not re-rendering components when updated

139 Views Asked by At
(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)

The (selected-item) function crerates a ref-cursor which tracks the :selected-item key in app-state. When you click a selected-item-button the title changes to reflect the new value that has been put into the map. However, this only works once. Pressing a different button does not cause the title to re-render again so the title is always stuck at the value of the first button you pressed.

Although, simply adding a merge with an additional keyword seems to make it work... (merging with an empty map doesn't work either, tried that!)

Is my understanding on ref cursors wrong?

1

There are 1 best solutions below

0
On BEST ANSWER

So, the issue was very simple.

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

should have been

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

Notice the item, because it's a cursor, is dereferenced.