Mais conteúdo relacionado Semelhante a Om (Cont.) (20) Mais de Taku Fukushima (7) Om (Cont.)3. OM SWEET OM: (HIGH-)FUNCTIONAL
FRONTEND ENGINEERING WITH
CLOJURESCRIPT AND REACT
9. THE REGULAR OM COMPNENTS ARE
VERBOSE
(defn topology-viewer [app owner]
(reify
om/IRender
(render [_]
(dom/div
(dom/svg #js {:width 200 :height 200
:style {:backgoundColor "grey"}}
(dom/circle #js {:cx 30 :cy 30 :r 25 :stroke "grey"
:strokeWidth 1 :fill "wheat"})
(dom/rect #js {:width 50 :height 50 :x 60 :y 10
:style {:fill "red" :stroke "black"
:strokeWidth 5 :opacity 0.5}})))))
10. OM-TOOLS PROVIDES USEFUL MACROS
(defcomponent topology-viewer [app owner]
(render [_]
(dom/div
(dom/svg {:width 200 :height 200
:style {:backgound-color "grey"}}
(dom/circle {:cx 30 :cy 30 :r 25 :stroke "grey"
:stroke-width 1 :fill "wheat"})
(dom/rect {:width 50 :height 50 :x 60 :y 10
:style {:fill "red" :stroke "black"
:stroke-width 5 :opacity 0.5}})))))
17. (require '[datascript :as d])
;; Implicit join, multi-valued attribute
(let [schema {:aka {:db/cardinality :db.cardinality/many}}
conn (d/create-conn schema)]
(d/transact! conn [ { :db/id -1
:name "Maksim"
:age 45
:aka ["Maks Otto von Stirlitz", "Jack Ryan"] } ])
(d/q '[ :find ?n ?a
:where [?e :aka "Maks Otto von Stirlitz"]
[?e :name ?n]
[?e :age ?a] ]
@conn))
;; => #{ ["Maksim" 45] }
18. (d/q '[ :find ?k ?x
:in [[?k [?min ?max]] ...] ?range
:where [(?range ?min ?max) [?x ...]]
[(even? ?x)] ]
{ :a [1 7], :b [2 4] }
range)
;; => #{ [:a 2] [:a 4] [:a 6] [:b 2] }
19. ;; Recursive rule
(d/q '[ :find ?u1 ?u2
:in $ %
:where (follows ?u1 ?u2) ]
[ [1 :follows 2]
[2 :follows 3]
[3 :follows 4] ]
'[ [(follows ?e1 ?e2)
[?e1 :follows ?e2]]
[(follows ?e1 ?e2)
[?e1 :follows ?t]
(follows ?t ?e2)] ])
;; => #{ [1 2] [1 3] [1 4]
;; [2 3] [2 4]
;; [3 4] }
20. ;; Aggregates
(d/q '[ :find ?color (max ?amount ?x) (min ?amount ?x)
:in [[?color ?x]] ?amount ]
[[:red 10] [:red 20] [:red 30] [:red 40] [:red 50]
[:blue 7] [:blue 8]]
3)
;; => [[:red [30 40 50] [10 20 30]]
;; [:blue [7 8] [7 8]]]
23. RETRIEVE JSON DATA RECURSIVELY
;; Retrieve endpoints for resources
(defn- build-db-helper [conn endpoint]
(let [done (go
(let [res (<! (http/get endpoint {:with-credentials? false}))
rs (json-decode (res :body))]
(if (not (nil? rs))
(d/transact! conn rs))
(doseq [r rs
[k v] r :when (valid-resource? k v)]
(<! (build-db-helper conn v)))))]
done))
24. BUILD IN-MEMORY DATABASE
POPULATING DATA RETRIEVED FROM
THE API SERVER
(defn build-db [root]
(let [schema {}
conn (d/create-conn schema)
c (chan)
db (chan)]
;; Prevent cursor-ification. Borrowed from the following page:
;; https://gist.github.com/swannodette/11308901
(extend-type d/DB
om/IToCursor
(-to-cursor
([this _] this)
([this _ _] this)))
...))
25. (go
(let [res (<! (http/get root {:with-credentials? false}))]
(reset! api-endpoints (json-decode (res :body)))
(>! c @api-endpoints)))
(let [db-init (chan)]
(go
(let [endpoints (<! c)
ks (for [[k v] endpoints
:when (valid-resource? k v)] k)
m (select-keys endpoints ks)]
(doseq [[k v] m] (<! (build-db-helper conn v)))
(>! db-init :ok)))
(go
(log :info "waiting for the db initialized...")
(<! db-init)
(log :info "done.")
(prn (d/q '[:find ?id ?rid
:where
[_ :id ?id]]
@conn))
(>! db @conn)))
27. REFERENCES
▸ Prismatic: http://getprismatic.com/home
▸ Om sweet Om: (high-)functional frontend engineering
with ClojureScript and React: http://
blog.getprismatic.com/om-sweet-om-high-functional-
frontend-engineering-with-clojurescript-and-react/
▸ Prismatic/schema https://github.com/Prismatic/
schema
29. REFERENCES
▸ Unofficial guide to Datomic internals http://
tonsky.me/blog/unofficial-guide-to-datomic-
internals/
Other pictures are distributed under © Taku Fukushima