I'm familiar with re-frame and have used it. The re-frame model works very well and I like it a lot.
This conversation was started over a year ago, before re-frame existed and before Om had ref cursors. The story now is quite different (for both Reagent and Om). On Sun, 19 Jul 2015 at 06:14 Kurt Mueller <[email protected]> wrote: > 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. > -- 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.
