Skip to content

Instantly share code, notes, and snippets.

@ThomasDeutsch
Created November 9, 2015 17:01
Show Gist options
  • Save ThomasDeutsch/2ce77d5c650a382c43cb to your computer and use it in GitHub Desktop.
Save ThomasDeutsch/2ce77d5c650a382c43cb 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]]
[om.dom :as dom]
[datascript.core :as d]
[cljs.pprint :as pp :refer [pprint]]))
(enable-console-print!)
;________________________________________________________________________
; |
; An attempt to display and mutate recursive data hold into DataScript |
; Works with [org.omcljs/om "1.0.0-alpha19-SNAPSHOT"] as of 2015-11-09 |
;________________________________________________________________________|
;__________________________________________________________
; |
; DB |
;__________________________________________________________|
(def conn (d/create-conn {:task/children {:db/valueType :db.type/ref
:db/isComponent true
:db/cardinality :db.cardinality/many}
:task/creator {:db/valueType :db.type/ref}}))
(d/transact! conn [{:db/id -1
:task/title "Om-Next Beta version"
:task/status :wip
:task/children [{:db/id -2
:task/title "Handle recursive query"
:task/status :open
:task/children [{:db/id -3
:task/title "Think a little more"
:task/status :open}]}
{:db/id -4
:task/title "Hammock a little more"
:task/status :open}]}
{:db/id -5
:tag/title "milestone 1"
:tag/important? true}
{:db/id -6
:tag/title "milestone 2"
:tag/important? false}
])
;__________________________________________________________
; |
; UI |
;__________________________________________________________|
(declare task-ui) ; Needed because of the recursion
(defui TaskUI
static om/IQuery
(query [this]
'[:db/id :task/title :task/status {:all-tags [:tag/title :tag/important?]} {:task/children ...}]) ;Magic appends with the recursice notation
Object
(render [this]
(let [{:keys [db/id task/title task/status task/children] :as task} (om/props this)
idty (om/ident this task)]
(dom/div #js {:style #js {:border "1px solid grey"
:borderRadius "4px"
:margin "3px"
:padding "3px"}}
(dom/h3 #js {}
(dom/button #js {:onClick #(om/transact! this `[(task/close ~task)])} "Close")
(str (name status) " - " title))
(apply dom/div nil (map task-ui children))))))
(def task-ui (om/factory TaskUI {:keyfn :db/id}))
(defui TasksList
static om/IQuery
(query [this]
`[{:tasks/all-tasks ~(om/get-query TaskUI)}])
Object
(render [this]
(let [{:keys [tasks/all-tasks]} (om/props this)]
(apply dom/div #js {}
(for [task all-tasks]
(task-ui task))))))
;__________________________________________________________
; |
; Read |
;__________________________________________________________|
(defmulti read om/dispatch)
(defmethod read :all-tags
[{:keys [state selector]} _ _]
(println "all-tags")
{:value (d/q '[:find [(pull ?e ?selector) ...]
:in $ ?selector
:where
[?e :tag/title]]
(d/db state) selector)})
(defmethod read :tasks/all-tasks
[{:keys [state selector]} key params]
(println "selector (all-tasks): " selector)
{:value (d/q '[:find [(pull ?e ?selector) ...]
:in $ ?selector
:where
[?e :task/title]]
(d/db state) selector)})
;__________________________________________________________
; |
; Mutation |
;__________________________________________________________|
(defmulti mutate om/dispatch)
(defmethod mutate 'task/close
[{:keys [state]} _ {:keys [db/id] :as params}]
{:action #(d/transact! conn [{:db/id id :task/status :closed}])})
;__________________________________________________________
; |
; Reconciler |
;__________________________________________________________|
(def parser (om/parser {:read read
:mutate mutate}))
(def reconciler (om/reconciler {:parser parser
:state conn}))
;__________________________________________________________
; |
; Root |
;__________________________________________________________|
(om/add-root! reconciler TasksList (gdom/getElement "app"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment