My feeling is that your app-state atom should contain everything that would be saved into a document if your user did a File->Save in a conventional desktop application. Given that, it wouldn't seem appropriate to put things like channels or flags for tracking mouse/hover state and that sort of thing into the app-state atom. I feel that that sort of thing should live in component local state.
I agree that things get a bit trickier in the case you outlined with the 'current-cat' example. You can pass multiple cursors to a component (https://github.com/swannodette/om/wiki/Cursors), so the cat-viewer component could rely on two cursors: one cursor to the list of kitties, and another to the :cat-viewer-widget entry which would allow it to transact! directly on the app state and set the current cat itself. An alternative approach is to have the cat-viewer-widget just pass an event on a channel when someone selects a cat. A parent component would then be responsible for pulling this event off the channel and transacting! on the app state to set the current cat. In my project, I have the exact same situation, except I'm displaying and selecting colors instead of cats (https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/appstate.cljs See :palette and :paint-color). I've decided to go with the second option, creating a parent component which has a cursor to basically the entire application state (which is less than ideal), and this component builds a child component whose job is to render the list of colors and pass any clicks/selections on those colors to the parent component via an async channel: https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/components/palette.cljs#L18 The parent component is then responsible for transacting! on the app-state - It's acting sort of like a controller for all child components, waiting for children to send events or requests over the channels it created in its component local state. As for the should you transact! or let someone else do it for you, I think that just seems like it has to be worked out on a case by case basis. I've mixed and matched a bit, and I don't see any benefit to letting another component transact! on your behalf if you can do it via your own cursor (https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/components/canvastools.cljs#L26) Those are my very un-informed two cents coming from a complete beginner :) Hopefully that's somehow helpful! On Friday, May 2, 2014 8:19:00 AM UTC+2, Sean Corfield wrote: > On Thu, May 1, 2014 at 10:32 PM, Elliot Block <[email protected]> wrote: > > > 1. "model"-ish data, e.g. if your app's about cats, a list of cats. > > > 2. "view"-ish data, like whether a given UI panel is shown or hidden > > > 3. coordination-ish data, like async channels so that components can talk > > to each other, e.g. to show or hide panels, to switch the cat being > > displayed. > > > > My understanding so far is: > > > > 1. app-state, cursors > > 2. local component state > > 3. :opts (shared readonly data) > > > > If that's not right, I look forward to being educated! > > -- > > Sean A Corfield -- (904) 302-SEAN > > An Architect's View -- http://corfield.org/ > > World Singles, LLC. -- http://worldsingles.com/ > > > > "Perfection is the enemy of the good." > > -- Gustave Flaubert, French realist novelist (1821-1880) -- 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.
