|
1 | 1 | (ns om-tutorial.core
|
2 | 2 | (:require [goog.dom :as gdom]
|
3 | 3 | [om.next :as om :refer-macros [defui]]
|
4 |
| - [om.dom :as dom])) |
| 4 | + [om.dom :as dom] |
| 5 | + [cljs.pprint :as pprint])) |
5 | 6 |
|
6 | 7 | (enable-console-print!)
|
7 | 8 |
|
8 | 9 | (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}]}) |
15 |
| - |
16 |
| -(defmulti read om/dispatch) |
17 |
| - |
18 |
| -(defn get-people [state key] |
19 |
| - (let [st @state] |
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 |
| 10 | + {:dashboard/items |
| 11 | + [{:id 0 :type :dashboard/post |
| 12 | + :author "Laura Smith" |
| 13 | + :title "A Post!" |
| 14 | + :content "Lorem ipsum dolor sit amet, quem atomorum te quo" |
| 15 | + :favorites 0} |
| 16 | + {:id 1 :type :dashboard/photo |
| 17 | + :title "A Photo!" |
| 18 | + :image "photo.jpg" |
| 19 | + :caption "Lorem ipsum" |
| 20 | + :favorites 0} |
| 21 | + {:id 2 :type :dashboard/post |
| 22 | + :author "Jim Jacobs" |
| 23 | + :title "Another Post!" |
| 24 | + :content "Lorem ipsum dolor sit amet, quem atomorum te quo" |
| 25 | + :favorites 0} |
| 26 | + {:id 3 :type :dashboard/graphic |
| 27 | + :title "Charts and Stufff!" |
| 28 | + :image "chart.jpg" |
| 29 | + :favorites 0} |
| 30 | + {:id 4 :type :dashboard/post |
| 31 | + :author "May Fields" |
| 32 | + :title "Yet Another Post!" |
| 33 | + :content "Lorem ipsum dolor sit amet, quem atomorum te quo" |
| 34 | + :favorites 0}]}) |
| 35 | + |
| 36 | +(defui Post |
| 37 | + static om/IQuery |
| 38 | + (query [this] |
| 39 | + [:id :type :title :author :content]) |
| 40 | + Object |
| 41 | + (render [this] |
| 42 | + (let [{:keys [title author content] :as props} (om/props this)] |
| 43 | + (dom/div nil |
| 44 | + (dom/h3 nil title) |
| 45 | + (dom/h4 nil author) |
| 46 | + (dom/p nil content))))) |
68 | 47 |
|
69 |
| - (def parser (om/parser {:read read :mutate mutate})) |
| 48 | +(def post (om/factory Post)) |
70 | 49 |
|
71 |
| - (def st (atom norm-data)) |
| 50 | +(defui Photo |
| 51 | + static om/IQuery |
| 52 | + (query [this] |
| 53 | + [:id :type :title :image :caption]) |
| 54 | + Object |
| 55 | + (render [this] |
| 56 | + (let [{:keys [title image caption]} (om/props this)] |
| 57 | + (dom/div nil |
| 58 | + (dom/h3 nil (str "Photo: " title)) |
| 59 | + (dom/div nil image) |
| 60 | + (dom/p nil "Caption: "))))) |
72 | 61 |
|
73 |
| - ;; inc mary points |
74 |
| - (parser {:state st} '[(points/increment {:name "Mary"})]) |
| 62 | +(def photo (om/factory Photo)) |
75 | 63 |
|
76 |
| - ;; updated in both: |
77 |
| - (parser {:state st} '[:list/one]) |
| 64 | +(defui Graphic |
| 65 | + static om/IQuery |
| 66 | + (query [this] |
| 67 | + [:id :type :title :image]) |
| 68 | + Object |
| 69 | + (render [this] |
| 70 | + (let [{:keys [title image]} (om/props this)] |
| 71 | + (dom/div nil |
| 72 | + (dom/h3 nil (str "Graphic: " title)) |
| 73 | + (dom/div nil image))))) |
78 | 74 |
|
79 |
| - (parser {:state st} '[:list/two]) |
80 |
| - |
81 |
| - ) |
| 75 | +(def graphic (om/factory Graphic)) |
82 | 76 |
|
83 |
| -(defui Person |
| 77 | +(defui DashboardItem |
84 | 78 | static om/Ident
|
85 |
| - (ident [this {:keys [name]}] |
86 |
| - [:person/by-name name]) |
| 79 | + (ident [this {:keys [id type]}] |
| 80 | + [type id]) |
87 | 81 | static om/IQuery
|
88 | 82 | (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 |
| 83 | + (zipmap |
| 84 | + [:dashboard/post :dashboard/photo :dashboard/graphic] |
| 85 | + (map #(conj % :favorites) |
| 86 | + [(om/get-query Post) |
| 87 | + (om/get-query Photo) |
| 88 | + (om/get-query Graphic)]))) |
112 | 89 | Object
|
113 | 90 | (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 |
| 91 | + (let [{:keys [id type favorites] :as props} (om/props this)] |
| 92 | + (dom/li |
| 93 | + #js {:style #js {:padding 10 :borderBottom "1px solid black"}} |
| 94 | + (dom/div nil |
| 95 | + (({:dashboard/post post |
| 96 | + :dashboard/photo photo |
| 97 | + :dashboard/graphic graphic} type) |
| 98 | + (om/props this))) |
| 99 | + (dom/div nil |
| 100 | + (dom/p nil (str "Favorites: " favorites)) |
| 101 | + (dom/button |
| 102 | + #js {:onClick |
| 103 | + (fn [e] |
| 104 | + (om/transact! this |
| 105 | + `[(dashboard/favorite {:ref [~type ~id]})]))} |
| 106 | + "Favorite!")))))) |
| 107 | + |
| 108 | +(def dashboard-item (om/factory DashboardItem)) |
| 109 | + |
| 110 | +(defui Dashboard |
122 | 111 | static om/IQuery
|
123 | 112 | (query [this]
|
124 |
| - (let [subquery (om/get-query Person)] |
125 |
| - `[{:list/one ~subquery} {:list/two ~subquery}])) |
| 113 | + [{:dashboard/items (om/get-query DashboardItem)}]) |
126 | 114 | Object
|
127 | 115 | (render [this]
|
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)])))) |
| 116 | + (let [{:keys [dashboard/items]} (om/props this)] |
| 117 | + (apply dom/ul |
| 118 | + #js {:style #js {:padding 0}} |
| 119 | + (map dashboard-item items))))) |
| 120 | + |
| 121 | +(defmulti read om/dispatch) |
| 122 | + |
| 123 | +(defmethod read :dashboard/items |
| 124 | + [{:keys [state]} k _] |
| 125 | + (let [st @state] |
| 126 | + {:value (into [] (map #(get-in st %)) (get st k))})) |
| 127 | + |
| 128 | +(defmulti mutate om/dispatch) |
| 129 | + |
| 130 | +(defmethod mutate 'dashboard/favorite |
| 131 | + [{:keys [state]} k {:keys [ref]}] |
| 132 | + {:action |
| 133 | + (fn [] |
| 134 | + (swap! state update-in (conj ref :favorites) inc))}) |
135 | 135 |
|
136 | 136 | (def reconciler
|
137 | 137 | (om/reconciler
|
138 | 138 | {:state init-data
|
139 | 139 | :parser (om/parser {:read read :mutate mutate})}))
|
140 | 140 |
|
141 |
| -(om/add-root! reconciler |
142 |
| - RootView (gdom/getElement "app")) |
| 141 | +(om/add-root! reconciler Dashboard (gdom/getElement "app")) |
0 commit comments