forked from jdubie/om-next-starter
/
core.cljs
123 lines (103 loc) · 3.4 KB
/
core.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
(ns om-starter.core
(:require [goog.dom :as gdom]
[om.next :as om :refer-macros [defui]]
[om-starter.util :as util]
[om.dom :as dom]
[sablono.core :refer-macros [html]]
cljs.pprint))
(enable-console-print!)
(defprotocol IQueryDelegate
(query-delegate [c]))
(defn get-query [x]
(if (implements? IQueryDelegate x)
(om/get-query (query-delegate x))
(om/get-query x)))
(defmulti mutate om/dispatch)
(defmulti read om/dispatch)
(defmethod read :the-list
[{:keys [state query ast] :as env} key {:keys [remote?]}]
(let [st @state]
(if-let [v (seq (om/db->tree query (get st key) st))]
{:value v}
{:value [] :the-list true})))
(defmethod read :item/by-name
[{:keys [state query query-root ast] :as env} key {:keys [remote?]}]
(let [st @state]
{:value (om/db->tree query query-root st)
:item ast}))
(defui ListItem
static om/Ident
(ident [this props]
[:item/by-name (:item/name props)])
static om/IQuery
(query [this]
[:item/name :item/another-basic-key])
Object
(render [this]
(html
[:li {:on-click (partial (:on-click (om/get-computed this)) this)}
(pr-str (:item/name (om/props this)))
", "
(pr-str (:item/another-basic-key (om/props this)))
", "
(pr-str (:item/details (om/props this)))])))
(def list-item (om/factory ListItem))
(defui ListOfItems
static IQueryDelegate
(query-delegate [this] ListItem)
Object
(render [this]
(html
[:ul
(for [item (om/props this)]
(list-item (om/computed item
{:on-click (:on-item-click (om/get-computed this))})))])))
(def list-of-items (om/factory ListOfItems))
(defui Details
static om/Ident
(ident [this props]
[:item/by-name (:item/name props)])
static om/IQuery
(query [this]
[:item/name :item/details])
Object
(render [this]
(dom/div nil
(dom/p nil
"Selected: "
(:item/name (om/props this)))
(dom/p nil
"Details: "
(:item/details (om/props this))))))
(def details (om/factory Details))
(defui Root
static om/IQueryParams
(params [this]
{:selected-item-ident [:item/by-name "B"]})
static om/IQuery
(query [this]
[{:the-list (get-query ListOfItems)}
{'?selected-item-ident (get-query Details)}])
Object
(render [this]
(let [{:keys [the-list]} (om/props this)
{:keys [selected-item-ident]} (om/get-params this)
selected-item (get (om/props this) selected-item-ident)]
(dom/div nil
(list-of-items (om/computed the-list
{:on-item-click #(om/set-query! this {:params {:selected-item-ident (om/get-ident %)}})}))
(details selected-item)))))
(def parser (om/parser {:read read :mutate mutate}))
(def reconciler
(om/reconciler
{:state {}
:merge-tree (fn [a b] (println "|merge" a b) (merge a b))
:merge-ident (fn [something tree ref props]
(js/console.info (with-out-str (cljs.pprint/pprint [tree ref props])))
(let [result (update-in tree ref merge props)]
(js/console.info (with-out-str (cljs.pprint/pprint result)))
result))
:parser parser
:remotes [:the-list :item]
:send util/send}))
(om/add-root! reconciler Root (gdom/getElement "app"))