On Wednesday, April 9, 2014 at 6:33:31 AM UTC-4, Daniel Kersten wrote:
> Hi,
> 
> 
> I'm trying to figure out the best way of structuring complex applications in 
> Om and I've hit a bit of a brick wall that I'm hoping someone can help me 
> with.
> 
> 
> 
> 
> I like the concept of cursors - narrow down the application state to what the 
> individual components actually need and allow them to read and modify only 
> that.
> 
> 
> The problem I'm having is that I don't know how to structure my state so that 
> the correct components have access to everything they need. Its easy if each 
> component only requires a strict subset of its parent, which is often the 
> case, but not always. I've hit a scenario where a component needs access to 
> two very different branches of the app state and I'm not sure how to pass it 
> to the component that needs it.
> 
> 
> 
> 
> As a (contrived) example, imagine you had an app for displaying orders in an 
> online store and the application state is something like this:
> 
> 
> (def app-state (atom {:items  [{:type "book" :price 123} {:type "cd" :price 
> 200}]
> 
> 
>                       :orders [{:date xxx :type "book" :count 3} {:date yyy 
> :type "cd" :count 1}]
>                       :filter "book"}))
> 
> 
> 
> 
> You can imagine that in a real application the :items and :orders branches 
> may be much deeper.
> 
> 
> Lets say I now have two components, one displaying the items (so it is passed 
> a cursor with path [:items]) and one displaying the orders (so it is passed a 
> cursor with path [:orders]). What if I now only want to display items and 
> orders where the type matches the filter?
> 
> 
> 
> 
> I have a few options:
> Restructure the app state in a way that gives each component access to what 
> it needs. This is not ideal as it means that I'm modelling my state after how 
> its being rendered rather than how its being processed and makes it very 
> application specific.
> 
> I can propagate the additional values down the component tree (eg using the 
> :state parameter to build), but this means that every other component before 
> the one that consumes it must now do additional work that it shouldn't need 
> to know about (couples the parent components too tightly to the child one)
> 
> Similarly, passing it in opts is not ideal as it has the same issue as #2, 
> with the added caveat that the component also won't rerender on change.I can 
> store the value in component local state and update it through a core.async 
> channel. This works well in the example above, where one or two simple values 
> need to be communicated, but gets unruly when the application is more complex.
> 
> I can pass the entire app state to each component (perhaps trough shared 
> state) and use transformation functions (similar to what Sean Grove did in 
> his recent slides) to transform the state into a local view for each 
> component. This means each component gets to select exactly what it needs to 
> access without worrying about what comes before or after it in the hierarchy, 
> but then you lose the benefit of cursors and automatic re-rendering when 
> something changes.
> 
> 
> 
> 
> I'm sure I'm missing something!
> 
> 
> Any tips appreciated.
> 
> 
> Dan.

Hi Daniel,

I haven't been using Om but I have been using re-frame. In re-frame, you create 
"subscriptions" where you specify what parts of the app state db you're 
interested in. Then, in your views, your component is composed of these 
subscriptions. 

I find this paradigm makes it really easy for my components to be able to 
listen for state changes even if the the state change is occurring in different 
places in the overall state data structure.

-- 
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