After hours of fiddling around with this and studying the reagent
source I came up with this solution using watches:

(defn register-reactive
  "Registers an handler which will be automatically triggered when
  value at given path in app-db has changed. The new handler will be
  provided with the new path value and also have the pure & trim-v
  middlewares injected."
  [id path f]
  (add-watch
   app-db id
   (fn [_ _ o n]
     (let [o (get-in o path)
           n (get-in n path)]
       (when-not (= o n) (dispatch-sync [id n])))))
  (register-handler id trim-v f))

Use like:

(register-reactive
 :foo [:tick]
 (fn [db tick]
   ;; (info :foo-tick tick)
   ;; do something
   (assoc db :foo ...)))

On 3 April 2015 at 23:51, Karsten Schmidt <[email protected]> wrote:
> Thanks, Daniel. Didn't know about `dispatch-sync` and this would
> definitely help to avoid the delay, but the fundamental question to me
> still is how to create reactions to handler changes *outside* reagent
> components. I'm not sure if re-frame or reagent actually supports this
> at all.
>
> AFAIK `(subscribe [:tick])` only makes sense inside a component fn.
> Given the following subscription handler:
>
> (register-sub :tick (fn [db _] (reaction (:tick @db))))
>
> I would like do to something like to do this outside a component:
>
> - subscribe to :tick
> - update dispatch-sync to dependent handler(s)
> - setup more subscriptions (:a, :b, :c ...)
> - have a set of components subscribing to :a, :b, :c etc.
>
> So every time :tick updates, everything will be re-run/re-drawn. The
> reasons why these dependent updates should be in handlers is that some
> of them will require results from earlier (intermediate) handler
> updates.
>
> Maybe I'm barking up the wrong tree here and should just solve this
> via core.async mult/tap or its pub/sub?
>
> On 3 April 2015 at 23:07, Daniel Kersten <[email protected]> wrote:
>> Have you tried using dispatch-sync?
>> https://github.com/Day8/re-frame/wiki/Bootstrap-An-Application#a-cheat and
>> https://github.com/Day8/re-frame/blob/master/src/re_frame/router.cljs#L54
>>
>> On Fri, 3 Apr 2015 at 22:50 Karsten Schmidt <[email protected]> wrote:
>>>
>>> I've been really enjoying my last month working on a largish app based
>>> on re-frame and not run into any probs. However, today I was going to
>>> refactor another project using animation and came across an issue
>>> which I'm somewhat stumped by:
>>>
>>> I created a global tick handler, which is supposed to be an event
>>> generator for various other handlers to update their data in the app
>>> db. Currently this :next-tick handler re-triggers itself like shown
>>> below and runs as predicted (~60Hz via requestAnimationFrame), but for
>>> the purpose of this question this could be triggered at any (lower)
>>> frequency:
>>>
>>> (defn re-trigger-timer [] (reagent/next-tick (fn [] (dispatch
>>> [:next-tick]))))
>>>
>>> (register-handler
>>>   :next-tick
>>>   (fn [db _]
>>>     (re-trigger-timer)
>>>     (update db :tick inc)))
>>>
>>> Now I'd like to have other handlers which (dynamically) subscribe to
>>> these tick changes, but they should be run without causing another
>>> 16ms delay caused from using the subscribe/dispatch mechanism - and I
>>> keep drawing a blank how to achieve this w/o modifying
>>> re-frame.db/app-db directly (outside an handler).
>>>
>>> Of course I could create a subscription for the :tick value, run the
>>> related code and return the computed data as derived view during
>>> re-drawing of the related components, but that kind of defeats the
>>> whole purpose and I'd really like these updates to happen in handlers.
>>> I'm sure there's a better way... no?! :)
>>>
>>> Could someone please clarify for me?
>>>
>>> FWIW the demo app in question is here:
>>> http://demo.thi.ng/geom/physics/strands.html
>>>
>>> For starters I'd like to update physics sim via an handler reacting to
>>> :tick changes, but there'll be others too...
>>>
>>> Thanks, K.
>>>
>>> --
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> ---
>>> You received this message because you are subscribed to the Google Groups
>>> "ClojureScript" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at http://groups.google.com/group/clojurescript.
>>
>> --
>> Note that posts from new members are moderated - please be patient with your
>> first post.
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "ClojureScript" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/clojurescript.
>
>
>
> --
> Karsten Schmidt
> http://postspectacular.com | http://toxiclibs.org | http://toxi.co.uk



-- 
Karsten Schmidt
http://postspectacular.com | http://toxiclibs.org | http://toxi.co.uk

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to