Created
January 13, 2016 15:34
-
-
Save griff/e2bd4b41bc9f3fee66fe to your computer and use it in GitHub Desktop.
First transaction render
This file contains 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]] | |
[om.dom :as dom])) | |
(enable-console-print!) | |
(def init-data | |
{:list/one {:modal {:visible false} | |
:list [{:name "John" :points 0 :manager [:person/by-name "Jeff"] :employees []} | |
{:name "Mary" :points 0 :employees []} | |
{:name "Bob" :points 0 :employees []}]} | |
:list/two {:modal {:visible false} | |
:list [{:name "Mary" :points 0 :age 27 :employees []} | |
{:name "Gwen" :points 0 :employees []} | |
{:name "Jeff" :points 0 :employees [{:name "John"}]}]}}) | |
(defmulti read om/dispatch) | |
#_(defn get-person [env key] | |
(let [st @state | |
p (get-in st key)] | |
(assoc p (om/parser parser)))) | |
(defn get-people [state key] | |
(let [st @state] | |
(into [] (map #(get-in st %)) (get st key)))) | |
(defmethod read :person/by-name | |
[{:keys [state query query/root] :as env} key params] | |
(do #_(.apply (.-log js/console) js/console (into-array ["PersonByName" env key])) | |
{:value (om/db->tree query root @state)})) | |
(defmethod read :list/one | |
[{:keys [state query query/root] :as env} key params] | |
(let [st @state] | |
#_(.apply (.-log js/console) js/console (into-array ["List one" key query root])) | |
{:value (om/db->tree query (:list/one st) st)})) | |
(defmethod read :list/two | |
[{:keys [state query query/root] :as env} key params] | |
(do | |
#_(.apply (.-log js/console) js/console (into-array ["List two" key query root])) | |
(let [st @state] | |
{:value (om/db->tree query (:list/two st) st)}))) | |
(defmulti mutate om/dispatch) | |
(defmethod mutate 'points/increment | |
[{:keys [state path]} _ {:keys [name]}] | |
{:action | |
(fn [] | |
(swap! state update-in | |
[:person/by-name name :points] | |
inc))}) | |
(defmethod mutate 'points/decrement | |
[{:keys [state path]} _ {:keys [name]}] | |
{:action | |
(fn [] | |
(swap! state update-in | |
[:person/by-name name :points] | |
#(let [n (dec %)] (if (neg? n) 0 n))))}) | |
(defmethod mutate 'modal/close | |
[{:keys [state] :as inp} k {:keys [path] :as muh} ] | |
{:value {:keys [:list/one]} | |
:action (fn [] | |
(swap! state update-in | |
(concat path [:visible]) | |
(constantly false)))}) | |
(defmethod mutate 'modal/open | |
[{:keys [state] :as inp} k {:keys [path] :as muh} ] | |
{:value {:keys [:list/one]} | |
:action | |
(fn [] | |
(swap! state update-in | |
(concat path [:visible]) | |
(constantly true)))}) | |
(declare list-view) | |
#_(defn all-points [person] | |
(let [{:keys [points employees]} person] | |
(reduce + points (map all-points employees)))) | |
(defui Person | |
static om/Ident | |
(ident [this {:keys [name]}] | |
[:person/by-name name]) | |
static om/IQuery | |
(query [this] | |
'[:name :points (get test) :age]) | |
Object | |
(render [this] | |
(println "Render Person" (-> this om/props :name) (count (-> this om/props :employees))) | |
(let [{:keys [name points] :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)]))} | |
"-") | |
#_(list-view employees))))) | |
(def person (om/factory Person {:keyfn :name})) | |
(defui Modal | |
static om/IQuery | |
(query [this] | |
'[:visible]) | |
Object | |
(render [this] | |
(let [{:keys [visible] :as props} (om/props this) | |
{:keys [header footer close-handler]} (om/get-computed this) | |
classes {:modal true | |
:fade true | |
:in visible}] | |
(println "Render Modal" (om/path this)) | |
(dom/div #js {:className "dialog"} | |
(when visible | |
(dom/div #js {:className "modal-backdrop fade in"})) | |
(dom/div #js {:className "modal fade in" :style #js {:display (if visible "block" "none")}} | |
(dom/div #js {:style #js {:top 0 | |
:right 0 | |
:bottom 0 | |
:left 0 | |
:position "absolute"} | |
:onClick #(when close-handler (close-handler % this))}) | |
(dom/div #js {:className "modal-dialog"} | |
(dom/div #js {:className "modal-content"} | |
(dom/div #js {:className "modal-header"} | |
(when close-handler | |
(dom/button | |
#js{:type "button" | |
:className "close" | |
:aria-hidden true | |
:onClick #(close-handler % this)} | |
"×")) | |
(dom/h4 #js {:className "modal-title"} header)) | |
(dom/div #js {:className "modal-body"} | |
(om/children this)) | |
(dom/div #js {:className "modal-footer"} | |
footer)))))))) | |
(def modal (om/factory Modal)) | |
(defui ListView | |
Object | |
(render [this] | |
(println "Render ListView" (-> this om/path)) | |
(let [list (om/props this)] | |
(apply dom/ul nil | |
(map person list))))) | |
(defn- compute-react-key [props] | |
(if-let [rk (:react-key props)] | |
rk | |
(if-let [idx (-> props meta :om-path)] | |
idx | |
js/undefined))) | |
(def list-view (om/factory ListView {:keyfn compute-react-key})) | |
(defui RootView | |
static om/IQuery | |
(query [this] | |
(let [subquery (om/get-query Person) | |
modal (om/get-query Modal)] | |
`[{:list/one [{:modal ~modal} {:list ~subquery}]} | |
{:list/two [{:modal ~modal} {:list ~subquery}]}])) | |
Object | |
(render [mis] | |
(let [{:keys [list/one list/two]} (om/props mis)] | |
#_(println "Render RootView" one two) | |
(dom/div nil | |
(dom/button #js {:onClick (fn [_] (om/transact! mis `[(modal/open {:path [:list/one :modal]})])) :type "button"} "Show List Muh") | |
(dom/button #js {:onClick (fn [_] (om/transact! mis `[(modal/open {:path [:list/two :modal]})])) :type "button"} "Show List B") | |
(modal (om/computed (:modal one) {:header "List Muh" | |
:close-handler (fn [_ m] (om/transact! mis `[(modal/close {:path ~(om/path m)})]))}) | |
(list-view (:list one))) | |
(modal (om/computed (:modal two) {:header "List B" | |
:close-handler (fn [_ m] (om/transact! mis `[(modal/close {:path ~(om/path m)})]))}) | |
(list-view (:list two))))))) | |
(def parser (om/parser {:read read :mutate mutate})) | |
(def reconciler | |
(om/reconciler | |
{:state init-data | |
:parser parser})) | |
(om/add-root! reconciler | |
RootView (gdom/getElement "app")) | |
(def norm-data (om/tree->db RootView init-data true)) | |
(comment | |
(in-ns 'om-tutorial.core) | |
(require '[cljs.pprint :as pp]) | |
(pp/pprint norm-data) | |
(parser {:state (atom norm-data)} '[{:list/two [:name {:employees ...}]}]) | |
(parser {:state (atom norm-data)} '[[:person/by-name "Jeff"]]) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment