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.

Reply via email to