Skip to content

Instantly share code, notes, and snippets.

@griffio
Created December 2, 2015 09:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save griffio/87e3ff9f88d9d8fbc7a5 to your computer and use it in GitHub Desktop.
Save griffio/87e3ff9f88d9d8fbc7a5 to your computer and use it in GitHub Desktop.
;;==================================================
;; People/Points
;;==================================================
(def init-data
{:list/one [{:name "Mary" :points 0}
{:name "Bob" :points 0}]
:list/two [{:name "Gwen" :points 0}
{:name "Mary" :points 0 :age 42}
{:name "Jeff" :points 0}]})
(defmulti read om/dispatch)
(defn get-people [state key]
(let [st @state]
(into [] (map #(get-in st %)) (get st key))))
(defmethod read :list/one
[{:keys [state] :as env} key params]
{:value (get-people state key)})
(defmethod read :list/two
[{:keys [state] :as env} key params]
{:value (get-people state key)})
(defmulti mutate om/dispatch)
(defmethod mutate 'points/increment
[{:keys [state]} _ {:keys [name]}]
{:action
(fn []
(swap! state update-in
[:person/by-name name :points]
inc))})
(defmethod mutate 'points/decrement
[{:keys [state]} _ {:keys [name]}]
{:action
(fn []
(swap! state update-in
[:person/by-name name :points]
#(let [n (dec %)] (if (neg? n) 0 n))))})
(defmethod mutate 'list/add
[{:keys [state]} _ _]
(let [name "Mike"
new-person {:name name :points 0}]
{:action
(fn []
(swap! state update :person/by-name assoc name new-person)
(swap! state update :list/one conj [:person/by-name name]))}))
(defui Person
static om/Ident
(ident [this {:keys [name]}]
[:person/by-name name])
static om/IQuery
(query [this]
'[:name :points :age])
Object
(render [this]
(println "Render Person" (-> this om/props :name))
(let [{:keys [points name foo] :as props} (om/props this)]
(dom/li nil
(dom/label nil (str name ", points: " points))
(dom/button
#js {:onClick
(fn [_] (om/transact! this `[(points/increment ~props)]))}
"+")
(dom/button
#js {:onClick
(fn [_] (om/transact! this `[(points/decrement ~props)]))}
"-")))))
(def person (om/factory Person {:keyfn :name}))
(defui ListView
Object
(render [this]
(println "Render ListView" (-> this om/path first))
(let [list (om/props this)]
(dom/ul nil
(map person list)))))
(def list-view (om/factory ListView))
(defui RootView
static om/IQuery
(query [this]
(let [subquery (om/get-query Person)]
`[{:list/one ~subquery} {:list/two ~subquery}]))
Object
(render [this]
(println "Render RootView")
(let [{:keys [list/one list/two]} (om/props this)]
(apply dom/div nil
[
(dom/h3 nil "List A")
(dom/button #js {:onClick
(fn [e]
(om/transact! this `[(list/add)]))} "add")
(list-view one)
(dom/h3 nil "List B")
(list-view two)]))))
(def reconciler
(om/reconciler
{:state init-data
:parser (om/parser {:read read :mutate mutate})}))
(om/add-root! reconciler
RootView (gdom/getElement "people"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment