Refactor: separate state and DOM
This commit is contained in:
parent
0cc5cc5dc8
commit
991807700b
5 changed files with 84 additions and 55 deletions
|
@ -49,7 +49,7 @@
|
|||
(go (doseq [grub sorted-grubs]
|
||||
(let [grub-event (-> grub
|
||||
(select-keys [:_id :grub :completed])
|
||||
(assoc :event :create))]
|
||||
(assoc :event :add))]
|
||||
(>! out grub-event))))
|
||||
out))
|
||||
|
||||
|
|
|
@ -3,40 +3,19 @@
|
|||
:refer [fan-in fan-out event-chan filter-chan do-chan do-chan! map-chan]]
|
||||
[grub-client.view :as view]
|
||||
[grub-client.websocket :as ws]
|
||||
[grub-client.state :as state]
|
||||
[cljs.core.async :refer [<! >! >!! chan close! timeout]]
|
||||
[cljs.reader])
|
||||
(:require-macros [grub-client.macros :refer [log logs go-loop]]
|
||||
[cljs.core.async.macros :refer [go]]))
|
||||
|
||||
(defn get-local-events []
|
||||
(fan-in [(view/get-added-events)
|
||||
(view/get-completed-events)
|
||||
(view/get-deleted-events)]))
|
||||
|
||||
(defmulti handle-event :event :default :unknown-event)
|
||||
|
||||
(defmethod handle-event :create [event]
|
||||
(view/add-grub event))
|
||||
|
||||
(defmethod handle-event :complete [event]
|
||||
(view/complete-grub event))
|
||||
|
||||
(defmethod handle-event :uncomplete [event]
|
||||
(view/uncomplete-grub event))
|
||||
|
||||
(defmethod handle-event :delete [event]
|
||||
(view/delete-grub event))
|
||||
|
||||
(defmethod handle-event :unknown-event [event]
|
||||
(logs "Cannot handle unknown event:" event))
|
||||
|
||||
(defn handle-grub-events []
|
||||
(let [local-events (get-local-events)
|
||||
(let [local-events (view/get-local-events)
|
||||
[local-events' local-events''] (fan-out local-events 2)
|
||||
remote-events (ws/get-remote-events)
|
||||
events (fan-in [local-events' remote-events])]
|
||||
(do-chan! ws/send-to-server local-events'')
|
||||
(go-loop (handle-event (<! events)))))
|
||||
(go-loop (state/handle-event (<! events)))))
|
||||
|
||||
(defn init []
|
||||
(view/render-body)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
`(.log js/console ~@args))
|
||||
|
||||
(defmacro logs [& args]
|
||||
(let [strings (map (fn [a] `(str ~a)) args)]
|
||||
(let [strings (map (fn [a] `(pr-str ~a)) args)]
|
||||
`(.log js/console ~@strings)))
|
||||
|
||||
(defmacro go-loop [& body]
|
||||
|
|
49
src-cljs/grub_client/state.cljs
Normal file
49
src-cljs/grub_client/state.cljs
Normal file
|
@ -0,0 +1,49 @@
|
|||
(ns grub-client.state
|
||||
(:require-macros [grub-client.macros :refer [log logs]]))
|
||||
|
||||
(def grubs (atom []))
|
||||
|
||||
(defn get-grub-with-index [grubs id]
|
||||
(let [grub-index (->> grubs
|
||||
(map-indexed vector)
|
||||
(filter #(= (:_id (second %)) id))
|
||||
(first)
|
||||
(first))
|
||||
grub (nth grubs grub-index)]
|
||||
[grub-index grub]))
|
||||
|
||||
(defmulti handle-event :event :default :unknown-event)
|
||||
|
||||
(defmethod handle-event :add [event]
|
||||
(let [grub (select-keys event [:_id :grub :completed])]
|
||||
(swap! grubs (fn [current] (conj current grub)))))
|
||||
|
||||
(defmethod handle-event :create [event]
|
||||
(let [grub (-> event
|
||||
(select-keys [:_id :grub])
|
||||
(assoc :completed false))]
|
||||
(swap! grubs (fn [current] (conj current grub)))))
|
||||
|
||||
(defmethod handle-event :complete [event]
|
||||
(swap! grubs
|
||||
(fn [current]
|
||||
(let [[grub-index grub] (get-grub-with-index current (:_id event))
|
||||
completed-grub (assoc grub :completed true)]
|
||||
(assoc current grub-index completed-grub)))))
|
||||
|
||||
(defmethod handle-event :uncomplete [event]
|
||||
(swap! grubs
|
||||
(fn [current]
|
||||
(let [[grub-index grub] (get-grub-with-index current (:_id event))
|
||||
incomplete-grub (assoc grub :completed false)]
|
||||
(assoc current grub-index incomplete-grub)))))
|
||||
|
||||
(defmethod handle-event :delete [event]
|
||||
(swap! grubs
|
||||
(fn [current]
|
||||
(vec (remove #(= (:_id %) (:_id event)) current)))))
|
||||
|
||||
(defmethod handle-event :unknown-event [event]
|
||||
(logs "Cannot handle unknown event:" event))
|
||||
|
||||
|
|
@ -1,21 +1,13 @@
|
|||
(ns grub-client.view
|
||||
(:require [grub-client.async-utils
|
||||
:refer [do-chan! do-chan event-chan map-chan fan-in filter-chan]]
|
||||
[grub-client.state :as state]
|
||||
[dommy.core :as dommy]
|
||||
[cljs.core.async :refer [<! >! chan]])
|
||||
(:require-macros [grub-client.macros :refer [log logs go-loop]]
|
||||
[dommy.macros :refer [deftemplate sel1 node]]
|
||||
[cljs.core.async.macros :refer [go]]))
|
||||
|
||||
(deftemplate grub-template [grub]
|
||||
[:tr {:id (:_id grub)}
|
||||
[:td
|
||||
[:div.checkbox.grubCheckbox [:label
|
||||
[:input {:type "checkbox"}]
|
||||
(:grub grub)]]]
|
||||
[:td
|
||||
[:button.grub-close.close {:type "button"} "×"]]])
|
||||
|
||||
(def add-grub-text
|
||||
(node [:input.form-control {:type "text" :placeholder "2 grubs"}]))
|
||||
|
||||
|
@ -36,28 +28,19 @@
|
|||
[:tbody#grubList]]]
|
||||
[:div.col-lg-4]]])
|
||||
|
||||
(deftemplate grub-template [grub]
|
||||
[:tr {:id (:_id grub)}
|
||||
[:td
|
||||
[:div.checkbox.grubCheckbox [:label
|
||||
[:input {:type "checkbox"
|
||||
:checked (:completed grub)}]
|
||||
(:grub grub)]]]
|
||||
[:td
|
||||
[:button.grub-close.close {:type "button"} "×"]]])
|
||||
|
||||
(defn render-body []
|
||||
(dommy/prepend! (sel1 :body) (main-template)))
|
||||
|
||||
(defn add-grub-to-dom [grub-obj]
|
||||
(logs "Add" grub-obj)
|
||||
(dommy/append! (sel1 :#grubList) (grub-template grub-obj)))
|
||||
|
||||
(defn add-grub [grub]
|
||||
(add-grub-to-dom grub))
|
||||
|
||||
(defn complete-grub [grub]
|
||||
(logs "Complete" grub)
|
||||
(aset (sel1 [(str "#" (:_id grub)) "input"]) "checked" true))
|
||||
|
||||
(defn uncomplete-grub [grub]
|
||||
(logs "Uncomplete" grub)
|
||||
(aset (sel1 [(str "#" (:_id grub)) "input"]) "checked" false))
|
||||
|
||||
(defn delete-grub [grub]
|
||||
(let [elem (sel1 (str "#" (:_id grub)))]
|
||||
(.removeChild (.-parentNode elem) elem)))
|
||||
|
||||
(defn get-add-grub-text []
|
||||
(let [text (dommy/value add-grub-text)]
|
||||
(dommy/set-value! add-grub-text "")
|
||||
|
@ -108,4 +91,22 @@
|
|||
(let [ids (map-chan #(.-id (.-parentNode (.-parentNode (.-target %)))) click-events)
|
||||
grub-events (map-chan (fn [id] {:event :delete :_id id}) ids)]
|
||||
grub-events)))
|
||||
|
||||
|
||||
(defn get-local-events []
|
||||
(fan-in [(get-added-events)
|
||||
(get-completed-events)
|
||||
(get-deleted-events)]))
|
||||
|
||||
(defn render-grub-list [grubs]
|
||||
(let [grub-list (sel1 :#grubList)
|
||||
sorted-grubs (sort-by :_id grubs)]
|
||||
(aset grub-list "innerHTML" "")
|
||||
(doseq [grub sorted-grubs]
|
||||
(logs "render-grub-list:" grub)
|
||||
(dommy/append! grub-list (grub-template grub)))))
|
||||
|
||||
(add-watch state/grubs
|
||||
:grub-add-watch
|
||||
(fn [key ref old new]
|
||||
(logs "state:" new)
|
||||
(render-grub-list new)))
|
||||
|
|
Loading…
Reference in a new issue