This commit is contained in:
Mike Thompson 2016-09-05 15:07:48 +10:00
commit 2dbb1668dd
4 changed files with 50 additions and 53 deletions

View File

@ -1,6 +0,0 @@
(ns todomvc.dev
(:require [todomvc.core :as todomvc]
[figwheel.client :as fw]))
(fw/start {:on-jsload todomvc/main
:websocket-url "ws://localhost:3450/figwheel-ws"})

View File

@ -1,28 +1,28 @@
(defproject todomvc-re-frame "0.8.0"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.227"]
[org.clojure/clojurescript "1.9.89"]
[reagent "0.6.0-rc"]
[re-frame "0.8.0"]
[binaryage/devtools "0.8.1"]
[secretary "1.2.3"]]
:plugins [[lein-cljsbuild "1.1.3"]
[lein-figwheel "0.5.4-7"]]
:plugins [[lein-cljsbuild "1.1.4"]
[lein-figwheel "0.5.6"]]
:hooks [leiningen.cljsbuild]
:profiles {:dev {:cljsbuild
{:builds {:client {:source-paths ["devsrc"]
:compiler {:main "todomvc.dev"
:asset-path "js"
:optimizations :none
:source-map true
:source-map-timestamp true}}}}}
:profiles {:dev {:cljsbuild
{:builds {:client {:compiler {:asset-path "js"
:optimizations :none
:source-map true
:source-map-timestamp true
:main "todomvc.core"}
:figwheel {:on-jsload "todomvc.core/main"}}}}}
:prod {:cljsbuild
{:builds {:client {:compiler {:optimizations :advanced
:elide-asserts true
:pretty-print false}}}}}}
{:builds {:client {:compiler {:optimizations :advanced
:elide-asserts true
:pretty-print false}}}}}}
:figwheel {:server-port 3450
:repl true}

View File

@ -1,6 +1,7 @@
(ns todomvc.db
(:require [cljs.reader]
[cljs.spec :as s]))
[cljs.spec :as s]
[re-frame.core :as re-frame]))
;; -- Spec --------------------------------------------------------------------
@ -18,20 +19,20 @@
;; None of this is strictly necessary. It could be omitted. But we find it
;; good practice.
(s/def ::id int?)
(s/def ::title string?)
(s/def ::done boolean?)
(s/def ::todo (s/keys :req-un [::id ::title ::done]))
(s/def ::todos (s/and ;; should use the :kind kw to s/map-of (not supported yet)
(s/map-of ::id ::todo) ;; in this map, each todo is keyed by its :id
#(instance? PersistentTreeMap %) ;; is a sorted-map (not just a map)
))
(s/def ::showing ;; what todos are shown to the user?
#{:all ;; all todos are shown
:active ;; only todos whose :done is false
:done ;; only todos whose :done is true
})
(s/def ::db (s/keys :req-un [::todos ::showing]))
(s/def ::id int?)
(s/def ::title string?)
(s/def ::done boolean?)
(s/def ::todo (s/keys :req-un [::id ::title ::done]))
(s/def ::todos (s/and ;; should use the :kind kw to s/map-of (not supported yet)
(s/map-of ::id ::todo) ;; in this map, each todo is keyed by its :id
#(instance? PersistentTreeMap %) ;; is a sorted-map (not just a map)
))
(s/def ::showing ;; what todos are shown to the user?
#{:all ;; all todos are shown
:active ;; only todos whose :done is false
:done ;; only todos whose :done is true
})
(s/def ::db (s/keys :req-un [::todos ::showing]))
;; -- Default app-db Value ---------------------------------------------------
;;
@ -40,9 +41,9 @@
;; Look in core.cljs for "(dispatch-sync [:initialise-db])"
;;
(def default-value ;; what gets put into app-db by default.
{:todos (sorted-map) ;; an empty list of todos. Use the (int) :id as the key
:showing :all}) ;; show all todos
(def default-value ;; what gets put into app-db by default.
{:todos (sorted-map) ;; an empty list of todos. Use the (int) :id as the key
:showing :all}) ;; show all todos
;; -- Local Storage ----------------------------------------------------------
@ -52,18 +53,18 @@
;; But we are not to load the setting for the "showing" filter. Just the todos.
;;
(def ls-key "todos-reframe") ;; localstore key
(defn localstore->todos
"Read in todos from localstore, and process into a map we can merge into app-db."
[]
(some->> (.getItem js/localStorage ls-key)
(cljs.reader/read-string) ;; stored as an EDN map.
(into (sorted-map)) ;; map -> sorted-map
(hash-map :todos))) ;; access via the :todos key
(def ls-key "todos-reframe") ;; localstore key
(defn todos->local-store
"Puts todos into localStorage"
[todos]
(.setItem js/localStorage ls-key (str todos))) ;; sorted-map writen as an EDN map
(.setItem js/localStorage ls-key (str todos))) ;; sorted-map writen as an EDN map
(re-frame/reg-cofx
:local-store-todos
(fn [cofx _]
"Read in todos from localstore, and process into a map we can merge into app-db."
(assoc cofx :local-store-todos
(some->> (.getItem js/localStorage ls-key)
(cljs.reader/read-string) ;; stored as an EDN map.
(into (sorted-map))))))

View File

@ -1,7 +1,8 @@
(ns todomvc.events
(:require
[todomvc.db :refer [default-value localstore->todos todos->local-store]]
[re-frame.core :refer [reg-event-db path trim-v after debug]]
[todomvc.db :refer [default-value todos->local-store]]
[re-frame.core :refer [reg-event-db reg-event-fx inject-cofx path trim-v
after debug]]
[cljs.spec :as s]))
@ -51,11 +52,12 @@
;; XXX make localstore a coeffect interceptor
;; usage: (dispatch [:initialise-db])
(reg-event-db ;; on app startup, create initial state
(reg-event-fx ;; on app startup, create initial state
:initialise-db ;; event id being handled
check-spec-interceptor ;; after the event handler runs, check that app-db matches the spec
(fn [_ _] ;; the handler being registered
(merge default-value (localstore->todos)))) ;; all hail the new state
[(inject-cofx :local-store-todos)
check-spec-interceptor] ;; after the event handler runs, check that app-db matches the spec
(fn [{:keys [db local-store-todos]} _] ;; the handler being registered
{:db (assoc default-value :todos local-store-todos)})) ;; all hail the new state
;; usage: (dispatch [:set-showing :active])