Last active
November 21, 2015 09:34
-
-
Save ThomasDeutsch/0080e4ec0a0a21bec943 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns om-tutorial.core | |
(:require | |
[goog.dom :as gdom] | |
[om.next :as om :refer-macros [defui]] | |
[datascript.core :as d] | |
[om.dom :as dom])) | |
(enable-console-print!) | |
;; ----------------------------------------------------------------------------- | |
;; DB | |
(def conn (d/create-conn {:list/one {:db/valueType :db.type/ref | |
:db/cardinality :db.cardinality/many} | |
:list/two {:db/valueType :db.type/ref | |
:db/cardinality :db.cardinality/many}})) | |
(d/transact! conn | |
[{:db/id -1 | |
:name "John" | |
:points 0} | |
{:db/id -2 | |
:name "Mary" | |
:points 0 | |
:age 27} | |
{:db/id -3 | |
:name "Bob" | |
:points 0} | |
{:db/id -4 | |
:name "Gwen" | |
:points 0} | |
{:db/id -5 | |
:name "Jeff" | |
:points 0} | |
;; root entity 0 will contain the two lists | |
;; as far as i know, this is not possible in datomic, but in datascript it is | |
;; a nice solution. See todo datascript app: | |
;; https://github.com/tonsky/datascript-todo/blob/gh-pages/src/datascript_todo/core.cljs#L38 | |
;; Because of this, i do not need to find the root entity. I can savely assume it is :db/id 0 | |
{:db/id 0 | |
:list/one [-1 -2 -3] | |
:list/two [-2 -4 -5]}]) | |
;; ----------------------------------------------------------------------------- | |
;; Parsing | |
(defmulti read om/dispatch) | |
(defn get-people [state key] | |
(let [st @state] | |
(into [] (map #(get-in st %)) (get st key)))) | |
(defmethod read :list/one | |
[{:keys [state query _ _]} key _] | |
{:value (-> (d/pull @state [{key query}] 0) | |
(get key))}) | |
(defmethod read :list/two | |
[{:keys [state query _ _]} key _] | |
{:value (-> (d/pull @state [{key query}] 0) | |
(get key))}) | |
(defmulti mutate om/dispatch) | |
(defmethod mutate 'points/increment | |
[{:keys [state]} _ {:keys [db/id points]}] | |
{:action | |
(fn [] | |
(d/transact! state [[:db/add id :points (inc points)]]))}) | |
(defmethod mutate 'points/decrement | |
[{:keys [state]} _ {:keys [db/id points]}] | |
{:action | |
(fn [] | |
(d/transact! state [[:db/add id :points (dec points)]]))}) | |
;; ----------------------------------------------------------------------------- | |
;; Components | |
(defui Person | |
static om/Ident | |
(ident [this {:keys [db/id]}] | |
[:db/id id]) | |
static om/IQuery | |
(query [this] | |
'[:db/id :name :points :age]) | |
Object | |
(render [this] | |
(println "Render Person" (-> this om/props :name)) | |
(let [{:keys [points name foo] :as props} (om/props this)] | |
(dom/li nil | |
(dom/label nil (str name ", points: " points)) | |
(dom/button | |
#js {:onClick | |
(fn [e] | |
(om/transact! this | |
`[(points/increment ~props)]))} | |
"+") | |
(dom/button | |
#js {:onClick | |
(fn [e] | |
(om/transact! this | |
`[(points/decrement ~props)]))} | |
"-"))))) | |
(def person (om/factory Person {:keyfn :name})) | |
(defui ListView | |
Object | |
(render [this] | |
(println "Render ListView" (-> this om/path first)) | |
(let [list (om/props this)] | |
(apply dom/ul nil | |
(map person list))))) | |
(def list-view (om/factory ListView)) | |
(defui RootView | |
static om/IQuery | |
(query [this] | |
(let [subquery (om/get-query Person)] | |
`[{:list/one ~subquery} {:list/two ~subquery}])) | |
Object | |
(render [this] | |
(println "Render RootView") | |
(let [{:keys [list/one list/two]} (om/props this)] | |
(apply dom/div nil | |
[(dom/h2 nil "List A") | |
(list-view one) | |
(dom/h2 nil "List B") | |
(list-view two)])))) | |
(def reconciler | |
(om/reconciler | |
{:state conn | |
:parser (om/parser {:read read :mutate mutate})})) | |
(om/add-root! reconciler | |
RootView (gdom/getElement "app")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment