James, thank you. That does help. My mental model of app-state being pure domain and view hierarchies effectively projecting their own structures is the thing to challenge.
The approach, if I may generalise is by all means project off app-state but keep it alongside (e.g. through opts as you show), rather than intermingled with? Essentially, it all went wrong when I mutated the cursor itself. Thanks James, Colin On 8 Nov 2014 16:17, "jack james" <[email protected]> wrote: > I don't think this is a bug. When you deref a cursor, you get the values > stored in the underlying app-state atom. Here, you're storing a cursor in > a component's local state. When you deref it later, you're still only > going to get the values stored the the cursor's underlying app-state atom... > > A couple things: > > 1) Storing cursors in local state is an anti-pattern. It's one of the few > patterns that we've seen clear guidance on, which is: don't do it. > > 2) In case this isn't clear: after you "decorate" a cursor with assoc, > it's still a cursor (with some extra stuff tagging along). We can verify > this with the "type" function: > > https://www.refheap.com/92913 > > That refheap also shows one of your options, which is to use om/value > (like deref, but intended for use during the render phase) to convert your > cursor to values, so that instead of storing a cursor in local state, > you're storing values. > > That would be better, but I still don't like it. You may be planning to > update your application state in your event handler with om/transact! or > om/update!, but those functions take cursors. So if you've already > converted your cursor to values, you won't be able to use those functions. > You would have to update app-state with another approach (callback, > channel, or ref-cursor). > > Also, remember the primary goal of react: to minimize the complexity of > managing state: > > http://facebook.github.io/react/docs/thinking-in-react.html > > "Figure out what the absolute minimal representation of the state of your > application needs to be and compute everything else you need on-demand." > > In this case, you're taking data that's already stored in app-state, and > storing it again in local state. I think you want to try avoid this > wherever possible. Here's one possible approach that doesn't use local > state at all: > > https://www.refheap.com/92914 > > HTH > > > On Saturday, November 8, 2014 7:44:51 AM UTC-6, Colin Yates wrote: > > Hi, > > > > I have found a bug, but it may well be (almost certainly is) in my > understanding ;). > > > > tldr; I decorate something from app-state and store as component-state. > In rendering I see the decorated thing but in on-click when I resolve the > cursor I see the undecorated thing. > > > > I have a hierarchy in my app-state and a tree-component to render it. > The tree component denormalises the tree so each node has an array of its > parent's ids and descendant ids (for example). I then persist this > decorated-tree as component state. > > > > The problem is that when I reference the decorated tree in the on-click, > I can see the cursor has access to the decorated tree but when I > denormalise it I see the undecorated tree. > > > > (As an aside, I originally tried it without component state and passed > the decorated tree as app-state to the delegate component but that > exhibited the same behaviour). > > > > I am sure I have missed something, but I don't see what - is this a bug > in om? I can by-pass this by simply storing everything in app-state in the > denormalised view, but that is not ideal - different components want to > render the same domain chunk differently (e.g. another component might show > this tree as a flattened list). > > > > The following code demonstrates the behaviour: > > > > [code] > > (defn the-component > > [_ owner] > > (reify > > om/IDisplayName > > (display-name [_] "Component") > > om/IRenderState > > (render-state [_ {:keys [node]}] > > (let [{:keys [id text children meta]} node] > > (js/console.log "NODE in rendering contains meta:" > > (clj->js (keys node))) > > (html > > [:li > > {:key id > > :on-click > > (fn [e] > > ;; prevent selection of the parent > > (. e stopPropagation) > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > ;; the cursor node contains the "meta" key if you expand > > ;; into .value.root.arr[2] > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > (js/console.log "(cursor)NODE in on-click (check > .value.root.arr[2]):") > > (js/console.log node) > > > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > ;; however it has all gone pear shape here... > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > (js/console.log "(deref)NODE in on-click no longer has > 'meta':" > > (clj->js (keys @node))))} > > "Click me"]))))) > > > > (defn tree > > [{:keys [node] :as data} owner] > > (reify > > om/IDisplayName > > (display-name [_] "Tree") > > om/IInitState > > (init-state [_] > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > ;; decorate the value of the cursor from app-state > > ;; but store locally > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > {:node (assoc node :meta {})}) > > om/IRenderState > > (render-state [_ {:keys [node]}] > > (om/build > > the-component > > nil > > {:init-state {:node node}})))) > > [/code] > > > > (any and all comments welcome!) > > > > Thanks. > > -- > Note that posts from new members are moderated - please be patient with > your first post. > --- > You received this message because you are subscribed to a topic in the > Google Groups "ClojureScript" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/clojurescript/SRqs211zf6E/unsubscribe. > To unsubscribe from this group and all its topics, 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.
