re-frame/src/re_frame/subs.cljs

44 lines
1.4 KiB
Plaintext
Raw Normal View History

2014-12-15 11:56:32 +00:00
(ns re-frame.subs
(:require
[reagent.ratom :refer [make-reaction] :refer-macros [reaction run!]]
2015-04-17 13:51:29 +00:00
[re-frame.db :refer [app-db]]
[re-frame.utils :refer [first-in-vector warn error]]))
2014-12-15 11:56:32 +00:00
2015-02-22 11:28:40 +00:00
;; maps from handler-id to handler-fn
2014-12-15 11:56:32 +00:00
(def ^:private key->fn (atom {}))
(defn clear-handlers!
"Unregisters all subscription handlers"
[]
(reset! key->fn {}))
2014-12-15 11:56:32 +00:00
(defn register
"Registers a handler function for an id"
2014-12-15 11:56:32 +00:00
[key-v handler-fn]
(if (contains? @key->fn key-v)
2015-02-24 21:26:47 +00:00
(warn "re-frame: overwriting subscription-handler for: " key-v)) ;; allow it, but warn.
2014-12-15 11:56:32 +00:00
(swap! key->fn assoc key-v handler-fn))
(defn subscribe
"Returns a reagent/reaction which observes a part of app-db"
([v]
(let [key-v (first-in-vector v)
handler-fn (get @key->fn key-v)]
(if (nil? handler-fn)
(error "re-frame: no subscription handler registered for: \"" key-v "\". Returning a nil subscription.")
(handler-fn app-db v))))
([v dynv]
(let [key-v (first-in-vector v)
handler-fn (get @key->fn key-v)]
(if (nil? handler-fn)
(error "re-frame: no subscription handler registered for: \"" key-v "\". Returning a nil subscription.")
(let [dyn-vals (reaction (mapv deref dynv))
sub (reaction (handler-fn app-db v @dyn-vals))]
;; handler-fn returns a reaction which is then wrapped in the sub reaction
;; need to double deref it to get to the actual value.
(reaction @@sub))))))