Skip to content

Instantly share code, notes, and snippets.

@ThomasDeutsch
Last active November 23, 2015 18:43
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 ThomasDeutsch/0f31328a72255fdc07f1 to your computer and use it in GitHub Desktop.
Save ThomasDeutsch/0f31328a72255fdc07f1 to your computer and use it in GitHub Desktop.
(ns om-tutorial.core
(:require
[goog.dom :as gdom]
[om.next :as om :refer-macros [defui]]
[datascript.core :as d]
[om.dom :as dom]
[cljs.pprint :as pprint]))
(enable-console-print!)
;; -----------------------------------------------------------------------------
;; DB
(def norm-tree-data (d/create-conn {:tree {:db/valueType :db.type/ref :db/cardinality :db.cardinality/many}
:children {:db/valueType :db.type/ref :db/cardinality :db.cardinality/many}
:node/by-id {:db/unique :db.unique/identity}}))
(d/transact! norm-tree-data
[{:node/by-id 3
:node-value 2
:children []}
{:node/by-id 4
:node-value 2
:children []}
{:node/by-id 2
:node-value 2
:children [[:node/by-id 4]]}
{:node/by-id 1
:node-value 1
:children [[:node/by-id 2]
[:node/by-id 3]]}
{:db/id 0 ;; my convention: 0 = root
:tree [[:node/by-id 1]]}])
;; -----------------------------------------------------------------------------
;; read / mutate
(declare norm-node)
(defmulti norm-tree-read om/dispatch)
(defmethod norm-tree-read :tree
[{:keys [state query] :as env} key _]
(let [st @state]
{:value (-> (d/pull st [{key query}] 0)
(get :tree)) }))
(defmethod norm-tree-read :node/by-id
[{:keys [state query query-root]} _ _]
(println "query-root: " query-root)
(d/pull @state query query-root))
(defmulti norm-tree-mutate om/dispatch)
(defmethod norm-tree-mutate 'tree/increment
[{:keys [state]} _ {:keys [id node-value]}]
{:action
(fn []
(d/transact! state [[:db/add id :node-value (inc node-value)]]))})
(defmethod norm-tree-mutate 'tree/decrement
[{:keys [state]} _ {:keys [id node-value]}]
{:action
(fn []
(d/transact! state [[:db/add id :node-value (max 0 (dec node-value))]]))})
(defn increment! [c id node-value]
(fn [e]
(om/transact! c `[(tree/increment {:id ~id :node-value ~node-value})])))
(defn decrement! [c id node-value]
(fn [e]
(om/transact! c `[(tree/decrement {:id ~id :node-value ~node-value})])))
;; -----------------------------------------------------------------------------
;; Components
(defui NormNode
static om/Ident
(ident [this {:keys [db/id]}]
[:node/by-id id])
static om/IQuery
(query [this]
'[:db/id :node-value {:children ...}])
Object
(render [this]
(let [{:keys [db/id node-value children]} (om/props this)]
(dom/li nil
(dom/div nil
(dom/label nil (str "Node value:" node-value))
(dom/button #js {:onClick (increment! this id node-value)} "+")
(dom/button #js {:onClick (decrement! this id node-value)} "-"))
(dom/ul nil
(map norm-node children))))))
(def norm-node (om/factory NormNode))
(defui NormTree
static om/IQuery
(query [this]
[{:tree (om/get-query NormNode)}])
Object
(render [this]
(let [{:keys [tree]} (om/props this)]
(dom/ul nil
(norm-node (first tree))))))
;; -----------------------------------------------------------------------------
;; Setup
(def norm-tree-parser
(om/parser {:read norm-tree-read
:mutate norm-tree-mutate}))
(def norm-tree-reconciler
(om/reconciler
{:state norm-tree-data
:parser norm-tree-parser
:pathopt true}))
(om/add-root! norm-tree-reconciler
NormTree (gdom/getElement "app"))
(pprint/pprint @(-> norm-tree-reconciler :config :indexer))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment