Thanks both - it does. My brain wasn't really engaged when I asked the
question. The salient point is that there are levels/layers in play
here.

I like your idea that dispatched events are application level events..

I might get shot for saying this, but I actually don't care
particularly about re-usable components as IME the effort required to
get them truly re-usable is less than the churn required to adapt them
to a new framework - maybe I am just not being strict/clean enough...
I do care very much about increasing ignorance/decoupling everywhere.

Unfortunately that ignorance is mostly in my head today it seems :).


On 27 March 2015 at 14:03, Daniel Kersten <dkers...@gmail.com> wrote:
> I'm currently tinkering with an approach where my code does not dispatch
> re-frame events at all, but rather uses my own emit function to emit
> signals[1]. I then, separately, have a signal->event map, so the (single
> global) signal handler then maps signals to events and dispatches these
> events to re-frame.
>
> What this gives me is that the components don't have to know what the (DOM)
> event callbacks actually do. Eg, instead of clicking the "add to list"
> button dispatching an [:add-to-list ...] event, it triggers an
> :add-to-list/clicked event and its up to the application to map this to the
> [:add-to-list ...] event. This way this component can be reused elsewhere by
> mapping the signal to whatever it makes sense for it to be mapped to.
>
> This indirection also means you can map one signal to trigger multiple
> re-frame events, although I haven't played with this enough yet to know if
> that is desirable or not.
>
> I like to think of re-frame events and handlers as the applications actions
> or capabilities - that is, the things that you can do. That way it makes
> sense that there is a 1:1 relationship between events and event handlers (eg
> only one handler can handle [:add-to-list ...]). That way, components emit
> "this thing just happened" signals which are mapped to "this outcome should
> be performed" actions/capabilities.
>
> Obviously reusable components can't always be made in isolation of the
> actions that they trigger, especially if they need to maintain
> transient/intermediary state. For this I like to define the component
> specific handlers as namespaced keywords, eg :my-list-editor/add-to-list
>
> I'm still undecided if such events should be dispatched directly or go
> through the signal indirection.
>
> Some final thing to note about the approach I'm investigating:
> 1. My signal->event mapper  can take an optional (pure) function to convert
> signal parameters to whatever data the handler expects.
> 2. I like to keep my handler functions pure too and do any side-effects (eg
> server comm or dispatching new events/emitting signals) in middleware.
>
> Hope that gives you some ideas.
>
> [1] I haven't got the terminology down yet :) I'm calling them signals for
> now because they're kinda like Qt's signals & slots, but I dunno if they
> really fit into the definition of signals from the FRP world.
>
> On Fri, 27 Mar 2015 at 13:58 Khalid Jebbari <khalid.jebb...@gmail.com>
> wrote:
>>
>> On Friday, March 27, 2015 at 2:39:37 PM UTC+1, Jamie Orchard-Hays wrote:
>> > Does it make sense to pass the reusable component's context as an
>> > argument to it? ie,
>> >
>> > (defn ReusableComponent [some-context] .... )
>> >
>> > Jamie
>> >
>> > On Mar 27, 2015, at 8:54 AM, Colin Yates <colin.ya...@gmail.com> wrote:
>> >
>> > > In re-frame event dispatching is handled by (dispatch [:discriminator
>> > > detail]). A corresponding (register-handler :discriminator (fn [db [_
>> > > detail]]) then reacts to that dispatched event.
>> > >
>> > > My question is how are people managing this with re-usable components?
>> > > For example, I have a tree and when selecting a node in that tree 
>> > > something
>> > > should happen. But this is where it gets all polymorphic as _what_ 
>> > > happens
>> > > depends on the client who instantiated the tree. I can see the following
>> > > ways forward:
>> > >
>> > > - tree is configured with a 'context' key which is combined with the
>> > > discriminator so rather than the tree emitting :node-selected it emits
>> > > :consumer-a-node-selected. Consumer a can then handle
>> > > consumer-a-node-selected and consumer b can handle (go on, guess)
>> > > consumer-b-node-selected
>> > > - a variation on the above involving writing your own dispatching
>> > > logic...
>> > > - tree doesn't use dispatch as the event bus, rather it takes in an
>> > > instance of a Protocol:
>> > >  IRespondToTree
>> > >  (on-node-select [this node])
>> > > - tree is parameterised with a map of fns {:node-selected-fn ...} etc.
>> > >
>> > > How would you all handle it? (I am leaning towards the first one).
>> > >
>> > > --
>> > > 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 clojurescript+unsubscr...@googlegroups.com.
>> > > To post to this group, send email to clojurescript@googlegroups.com.
>> > > Visit this group at http://groups.google.com/group/clojurescript.
>>
>> Not sure I'm going to answer the question directly, since I've never used
>> re-frame, Reagent or Om. I'm just an experienced React.js developer VERY
>> interested with Clojure(Script).
>>
>> If you want reusable components, whatever wrapper you use around React,
>> here's the plan.
>>
>> You should create 2 types of components : dumb and smart. Dumb components
>> do 2 simple things : display stuff and handle input/events. The way they
>> handle should be agnostic to any kind of library and should use only
>> language-level feature. Functions. So the dumb component use function it's
>> been passed and call it with the input/event. The smart components wrap dumb
>> components and connect to the outside world with whatever your stack uses
>> (channels, events, ratoms, what not).
>>
>> This way your dumb components are always reusable, whatever stack/project
>> they're incorporated in. They can also be displayed in a simple page for
>> your graphics or HTML/CSS team to check their look. The smart components
>> handle whatever logic you want to put in them. So from a stack/page/project
>> to another, only the smart components change, no the dumb ones. This keep UI
>> consistent and separate concerns.
>>
>> Hope it's clear and helpful.
>>
>> --
>> 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 clojurescript+unsubscr...@googlegroups.com.
>> To post to this group, send email to clojurescript@googlegroups.com.
>> 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 clojurescript+unsubscr...@googlegroups.com.
> To post to this group, send email to clojurescript@googlegroups.com.
> 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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to