Skip to content

Commit c3fb1d6

Browse files
committed
Identity and normalization
1 parent 8d77e34 commit c3fb1d6

File tree

1 file changed

+125
-33
lines changed

1 file changed

+125
-33
lines changed

src/om_tutorial/core.cljs

+125-33
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,140 @@
33
[om.next :as om :refer-macros [defui]]
44
[om.dom :as dom]))
55

6-
(def app-state
7-
(atom
8-
{:app/title "Animals"
9-
:animals/list
10-
[[1 "Ant"] [2 "Antelope"] [3 "Bird"] [4 "Cat"] [5 "Dog"]
11-
[6 "Lion"] [7 "Mouse"] [8 "Monkey"] [9 "Snake"] [10 "Zebra"]]}))
6+
(enable-console-print!)
127

13-
(defmulti read (fn [env key params] key))
8+
(def init-data
9+
{:list/one [{:name "John" :points 0}
10+
{:name "Mary" :points 0}
11+
{:name "Bob" :points 0}]
12+
:list/two [{:name "Mary" :points 0 :age 27}
13+
{:name "Gwen" :points 0}
14+
{:name "Jeff" :points 0}]})
1415

15-
(defmethod read :default
16-
[{:keys [state] :as env} key params]
16+
(defmulti read om/dispatch)
17+
18+
(defn get-people [state key]
1719
(let [st @state]
18-
(if-let [[_ value] (find st key)]
19-
{:value value}
20-
{:value :not-found})))
21-
22-
(defmethod read :animals/list
23-
[{:keys [state] :as env} key {:keys [start end]}]
24-
{:value (subvec (:animals/list @state) start end)})
25-
26-
(defui AnimalsList
27-
static om/IQueryParams
28-
(params [this]
29-
{:start 0 :end 10})
20+
(into [] (map #(get-in st %)) (get st key))))
21+
22+
(defmethod read :list/one
23+
[{:keys [state] :as env} key params]
24+
{:value (get-people state key)})
25+
26+
(defmethod read :list/two
27+
[{:keys [state] :as env} key params]
28+
{:value (get-people state key)})
29+
30+
(comment
31+
32+
;; IDENTITY
33+
34+
(in-ns 'om-tutorial.core)
35+
(require '[cljs.pprint :as pp])
36+
(def norm-data (om/tree->db RootView init-data true))
37+
38+
;; normalized data
39+
(pp/pprint norm-data)
40+
41+
(def parser (om/parser {:read read}))
42+
43+
;; not normalized
44+
(parser {:state (atom norm-data)} '[:list/one])
45+
46+
)
47+
48+
(defmulti mutate om/dispatch)
49+
50+
(defmethod mutate 'points/increment
51+
[{:keys [state]} _ {:keys [name]}]
52+
{:action
53+
(fn []
54+
(swap! state update-in
55+
[:person/by-name name :points]
56+
inc))})
57+
58+
(defmethod mutate 'points/decrement
59+
[{:keys [state]} _ {:keys [name]}]
60+
{:action
61+
(fn []
62+
(swap! state update-in
63+
[:person/by-name name :points]
64+
#(let [n (dec %)] (if (neg? n) 0 n))))})
65+
66+
67+
(comment
68+
69+
(def parser (om/parser {:read read :mutate mutate}))
70+
71+
(def st (atom norm-data))
72+
73+
;; inc mary points
74+
(parser {:state st} '[(points/increment {:name "Mary"})])
75+
76+
;; updated in both:
77+
(parser {:state st} '[:list/one])
78+
79+
(parser {:state st} '[:list/two])
80+
81+
)
82+
83+
(defui Person
84+
static om/Ident
85+
(ident [this {:keys [name]}]
86+
[:person/by-name name])
87+
static om/IQuery
88+
(query [this]
89+
'[:name :points])
90+
Object
91+
(render [this]
92+
(println "Render Person" (-> this om/props :name))
93+
(let [{:keys [points name foo] :as props} (om/props this)]
94+
(dom/li nil
95+
(dom/label nil (str name ", points: " points))
96+
(dom/button
97+
#js {:onClick
98+
(fn [e]
99+
(om/transact! this
100+
`[(points/increment ~props)]))}
101+
"+")
102+
(dom/button
103+
#js {:onClick
104+
(fn [e]
105+
(om/transact! this
106+
`[(points/decrement ~props)]))}
107+
"-")))))
108+
109+
(def person (om/factory Person {:keyfn :name}))
110+
111+
(defui ListView
112+
Object
113+
(render [this]
114+
(println "Render ListView" (-> this om/path first))
115+
(let [list (om/props this)]
116+
(apply dom/ul nil
117+
(map person list)))))
118+
119+
(def list-view (om/factory ListView))
120+
121+
(defui RootView
30122
static om/IQuery
31123
(query [this]
32-
'[:app/title (:animals/list {:start ?start :end ?end})])
124+
(let [subquery (om/get-query Person)]
125+
`[{:list/one ~subquery} {:list/two ~subquery}]))
33126
Object
34127
(render [this]
35-
(let [{:keys [app/title animals/list]} (om/props this)]
36-
(dom/div nil
37-
(dom/h2 nil title)
38-
(apply dom/ul nil
39-
(map
40-
(fn [[i name]]
41-
(dom/li nil (str i ". " name)))
42-
list))))))
128+
(println "Render RootView")
129+
(let [{:keys [list/one list/two]} (om/props this)]
130+
(apply dom/div nil
131+
[(dom/h2 nil "List A")
132+
(list-view one)
133+
(dom/h2 nil "List B")
134+
(list-view two)]))))
43135

44136
(def reconciler
45137
(om/reconciler
46-
{:state app-state
47-
:parser (om/parser {:read read})}))
138+
{:state init-data
139+
:parser (om/parser {:read read :mutate mutate})}))
48140

49141
(om/add-root! reconciler
50-
AnimalsList (gdom/getElement "app"))
142+
RootView (gdom/getElement "app"))

0 commit comments

Comments
 (0)