commit
192b93c9f6
14
CHANGES.md
14
CHANGES.md
|
@ -1,10 +1,22 @@
|
|||
|
||||
## v0.3.1 (2015-04-18)
|
||||
|
||||
Various small improvements and bug fixes:
|
||||
|
||||
- log-ex middleware added to core api (it was a mistake that it was missing)
|
||||
- modest improves to simple example. Better comments, layout, etc.
|
||||
- the anonymous functions in standard middleware now have meaningful
|
||||
names, which makes stack traces easier to understand.
|
||||
- #24 - Fix missing paren in README
|
||||
- #31 - Fix list formatting in README
|
||||
- #32 - fix a broken wiki link
|
||||
- #30 - Fix up the enrich docstring
|
||||
|
||||
|
||||
## v0.3.0 (2015-04-15)
|
||||
|
||||
### Headline
|
||||
|
||||
|
||||
- the middleware `after` and `enrich` now call the supplied function `f` with
|
||||
both `db` and `v` (previously just `db`). Because javascript is so forgiving
|
||||
about function arity, this change is backwards compatible.
|
||||
|
|
|
@ -670,7 +670,7 @@ Let's sketch out the situation described above ...
|
|||
{:name "c" :val 23 :flag "y"}])
|
||||
|
||||
(def app-db (reagent/atom {:items L
|
||||
:sort-by :name}) ;; sorted by the :name attribute
|
||||
:sort-by :name})) ;; sorted by the :name attribute
|
||||
```
|
||||
|
||||
The subscription-handler might be written:
|
||||
|
@ -897,7 +897,7 @@ Collectively, event handlers provide the control logic in a re-frame application
|
|||
An event handler is a pure function of two parameters:
|
||||
|
||||
1. current value in `app-db`. Note: that's the map **in** `app-db`, not the atom itself.
|
||||
2 an event (represented as a vector)
|
||||
2. an event (represented as a vector)
|
||||
|
||||
It returns the new value which should be reset! into `app-db`.
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
</div>
|
||||
<script src="target/client.js"></script>
|
||||
<script>
|
||||
simpleexample.core.run();
|
||||
window.onload = function () {
|
||||
simpleexample.core.run();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
(defproject simple-re-frame "0.5.0-alpha3"
|
||||
(defproject simple-re-frame "0.5.0"
|
||||
:dependencies [[org.clojure/clojure "1.6.0"]
|
||||
[org.clojure/clojurescript "0.0-2816"]
|
||||
[reagent "0.5.0-alpha3"]
|
||||
[re-frame "0.3.0"]
|
||||
[figwheel "0.2.3-SNAPSHOT"]]
|
||||
[reagent "0.5.0"]
|
||||
[re-frame "0.3.1"]
|
||||
[figwheel "0.2.6"]]
|
||||
|
||||
:plugins [[lein-cljsbuild "1.0.4"]
|
||||
[lein-figwheel "0.2.3-SNAPSHOT"]]
|
||||
|
|
|
@ -3,103 +3,112 @@
|
|||
(:require [reagent.core :as reagent :refer [atom]]
|
||||
[re-frame.core :refer [register-handler
|
||||
path
|
||||
register-sub
|
||||
dispatch
|
||||
register-sub
|
||||
dispatch
|
||||
dispatch-sync
|
||||
subscribe]]))
|
||||
|
||||
|
||||
;; trigger a dispatch every second
|
||||
(defonce time-updater (js/setInterval
|
||||
#(dispatch [:timer (js/Date.)]) 1000))
|
||||
|
||||
;;; this is the initial state
|
||||
(defonce initial-state
|
||||
(def initial-state
|
||||
{:timer (js/Date.)
|
||||
:time-color "#f34"})
|
||||
|
||||
;; Handlers
|
||||
;-------------------------------------------------------------
|
||||
|
||||
;; This handler sets the initial state
|
||||
(register-handler
|
||||
;; the handler is passed a map (not an atom) and must return the new state
|
||||
;; of the db
|
||||
:initialize
|
||||
;; -- Event Handlers ----------------------------------------------------------
|
||||
|
||||
|
||||
(register-handler ;; setup initial state
|
||||
:initialize ;; usage: (submit [:initialize])
|
||||
(fn
|
||||
[db _]
|
||||
(merge db initial-state)))
|
||||
(merge db initial-state))) ;; what it returns becomes the new state
|
||||
|
||||
|
||||
;; This handler changes the color of the displayed time
|
||||
(register-handler
|
||||
;;; register-handler can take 3 arguments to allow you to insert middleware
|
||||
;;; see https://github.com/Day8/re-frame/wiki/Handler-Middleware
|
||||
:time-color
|
||||
(path [:time-color])
|
||||
:time-color ;; usage: (submit [:time-color 34562])
|
||||
(path [:time-color]) ;; this is middleware
|
||||
(fn
|
||||
;; the path handler allows you to get directly to items in the database
|
||||
;; return the value you want assoc'd in
|
||||
[time-color [_ value]]
|
||||
[time-color [_ value]] ;; path middleware adjusts the first parameter
|
||||
value))
|
||||
|
||||
;; This handler changes the value of the time
|
||||
|
||||
(register-handler
|
||||
:timer
|
||||
(fn
|
||||
;; the first item in the second argument is :timer the second is the
|
||||
;; new value
|
||||
[db [_ value]]
|
||||
(assoc db :timer value)))
|
||||
(assoc db :timer value))) ;; return the new version of db
|
||||
|
||||
|
||||
;; -- Subscription Handlers ---------------------------------------------------
|
||||
|
||||
|
||||
;; add subscriptions to :timer and :time-color
|
||||
(register-sub
|
||||
:timer
|
||||
(fn
|
||||
[db _]
|
||||
;; you need to wrap your subscription code in a reaction
|
||||
(reaction (:timer @db))))
|
||||
[db _] ;; db is the app-db atom
|
||||
(reaction (:timer @db)))) ;; wrap the compitation in a reaction
|
||||
|
||||
|
||||
(register-sub
|
||||
:time-color
|
||||
(fn
|
||||
[db _]
|
||||
;; you need to wrap your subscription code in a reaction
|
||||
(reaction (:time-color @db))))
|
||||
|
||||
(dispatch [:initialize])
|
||||
|
||||
;; -- View Components ---------------------------------------------------------
|
||||
|
||||
(defn greeting [message]
|
||||
(defn greeting
|
||||
[message]
|
||||
[:h1 message])
|
||||
|
||||
(defn clock []
|
||||
|
||||
(defn clock
|
||||
[]
|
||||
(let [time-color (subscribe [:time-color])
|
||||
timer (subscribe [:timer])]
|
||||
;;; wrap your component in a function to use the suscription
|
||||
(fn []
|
||||
;; note that the initialize call will not be dispatched immediately
|
||||
;; as it is an async call
|
||||
(when @timer
|
||||
(let [time-str (-> @timer .toTimeString (clojure.string/split " ") first)]
|
||||
[:div.example-clock
|
||||
{:style {:color @time-color}}
|
||||
time-str])))))
|
||||
|
||||
(defn color-input []
|
||||
(fn clock-render
|
||||
[]
|
||||
(let [time-str (-> @timer
|
||||
.toTimeString
|
||||
(clojure.string/split " ")
|
||||
first)
|
||||
style {:style {:color @time-color}}]
|
||||
[:div.example-clock style time-str]))))
|
||||
|
||||
|
||||
(defn color-input
|
||||
[]
|
||||
(let [time-color (subscribe [:time-color])]
|
||||
;;; wrap your component in a function to use the suscription
|
||||
(fn []
|
||||
[:div.color-input
|
||||
"Time color: "
|
||||
[:input {:type "text"
|
||||
:value @time-color
|
||||
:on-change #(dispatch
|
||||
[:time-color (-> % .-target .-value)])}]])))
|
||||
|
||||
(defn simple-example []
|
||||
(fn color-input-render
|
||||
[]
|
||||
[:div.color-input
|
||||
"Time color: "
|
||||
[:input {:type "text"
|
||||
:value @time-color
|
||||
:on-change #(dispatch
|
||||
[:time-color (-> % .-target .-value)])}]])))
|
||||
|
||||
(defn simple-example
|
||||
[]
|
||||
[:div
|
||||
[greeting "Hello world, it is now"]
|
||||
[clock]
|
||||
[color-input]])
|
||||
|
||||
(defn ^:export run []
|
||||
|
||||
;; -- Entry Point -------------------------------------------------------------
|
||||
|
||||
|
||||
(defn ^:export run
|
||||
[]
|
||||
(dispatch-sync [:initialize])
|
||||
(reagent/render [simple-example]
|
||||
(js/document.getElementById "app")))
|
||||
(js/document.getElementById "app")))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(defproject todomvc-re-frame "0.3.0"
|
||||
(defproject todomvc-re-frame "0.3.1"
|
||||
:dependencies [[org.clojure/clojure "1.6.0"]
|
||||
[org.clojure/clojurescript "0.0-2816"]
|
||||
[reagent "0.5.0"]
|
||||
[re-frame "0.3.0"]
|
||||
[re-frame "0.3.1"]
|
||||
[secretary "1.2.1"]]
|
||||
|
||||
:plugins [[lein-cljsbuild "1.0.4"]]
|
||||
|
|
|
@ -7,17 +7,17 @@
|
|||
|
||||
|
||||
(defn filter-fn-for
|
||||
[showing-kw]
|
||||
(case showing-kw
|
||||
:active (complement :done)
|
||||
:done :done
|
||||
:all identity))
|
||||
[showing-kw]
|
||||
(case showing-kw
|
||||
:active (complement :done)
|
||||
:done :done
|
||||
:all identity))
|
||||
|
||||
|
||||
(defn completed-count
|
||||
"return the count of todos for which :done is true"
|
||||
[todos]
|
||||
(count (filter :done (vals todos))))
|
||||
"return the count of todos for which :done is true"
|
||||
[todos]
|
||||
(count (filter :done (vals todos))))
|
||||
|
||||
|
||||
;; -- Subscription handlers and registration ---------------------------------
|
||||
|
@ -25,26 +25,26 @@
|
|||
(register-sub
|
||||
:todos ;; usage: (subscribe [:todos])
|
||||
(fn [db _]
|
||||
(reaction (vals (:todos @db)))))
|
||||
(reaction (vals (:todos @db)))))
|
||||
|
||||
(register-sub
|
||||
:visible-todos
|
||||
(fn [db _]
|
||||
(reaction (let [filter-fn (filter-fn-for (:showing @db))
|
||||
todos (vals (:todos @db))]
|
||||
(filter filter-fn todos)))))
|
||||
(reaction (let [filter-fn (filter-fn-for (:showing @db))
|
||||
todos (vals (:todos @db))]
|
||||
(filter filter-fn todos)))))
|
||||
|
||||
(register-sub
|
||||
:completed-count
|
||||
(fn [db _]
|
||||
(reaction (completed-count (:todos @db)))))
|
||||
(reaction (completed-count (:todos @db)))))
|
||||
|
||||
(register-sub
|
||||
:footer-stats
|
||||
(fn [db _]
|
||||
(reaction
|
||||
(let [todos (:todos @db)
|
||||
completed-count (completed-count todos)
|
||||
active-count (- (count todos) completed-count)
|
||||
showing (:showing @db)]
|
||||
[active-count completed-count showing])))) ;; tuple
|
||||
(reaction
|
||||
(let [todos (:todos @db)
|
||||
completed-count (completed-count todos)
|
||||
active-count (- (count todos) completed-count)
|
||||
showing (:showing @db)]
|
||||
[active-count completed-count showing])))) ;; tuple
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(defproject re-frame "0.3.0"
|
||||
(defproject re-frame "0.3.1"
|
||||
:description "A Clojurescript MVC-like Framework For Writing SPAs Using Regent."
|
||||
:url "https://github.com/Day8/re-frame.git"
|
||||
:license {:name "MIT"}
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
(def enrich middleware/enrich)
|
||||
(def trim-v middleware/trim-v)
|
||||
(def after middleware/after)
|
||||
; (def log-events middleware/log-events)
|
||||
(def log-ex middleware/log-ex)
|
||||
|
||||
|
||||
|
||||
;; -- Convenience API -------
|
||||
|
||||
;; Almost 100% of handlers will be pure, so make it easy to
|
||||
;; register with "pure" middleware in the correct position.
|
||||
;; register with "pure" middleware in the correct (left-hand-side) position.
|
||||
(defn register-handler
|
||||
([id handler]
|
||||
(handlers/register-base id pure handler))
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
....)
|
||||
"
|
||||
[handler]
|
||||
(fn new-handler
|
||||
(fn trim-v-handler
|
||||
[db v]
|
||||
(handler db (vec (rest v)))))
|
||||
|
||||
|
@ -140,16 +140,16 @@
|
|||
complete reassesment of duplication errors and warnings. Eg: that edit
|
||||
update might have introduced a new duplicate or removed one. Same with a
|
||||
todo removal.
|
||||
And to perform this enrichment, a function has inspect all the todos,
|
||||
And to perform this enrichment, a function has to inspect all the todos,
|
||||
possibly set flags on each, and set some overall list of duplicates.
|
||||
And this duplicates checking might be just one check amoung a number.
|
||||
And this duplication check might just be one check amoung many.
|
||||
\"f\" would need to be both adding and removing the duplicate warnings.
|
||||
By applying \"f\" in middleware, we keep the handlers simple and yet we
|
||||
ensure this important step is not missed. "
|
||||
ensure this important step is not missed."
|
||||
[f]
|
||||
(fn middleware
|
||||
[handler]
|
||||
(fn validate-handler
|
||||
(fn enrich-handler
|
||||
[db v]
|
||||
(f (handler db v) v))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue