I see. Thanks again. On Saturday, 8 November 2014 16:56:09 UTC, jack james wrote: > I try to avoid these types of generalizations. There's nothing inherently > wrong with "decorating" a cursor, and it will work fine in many scenarios. > But when you need app-state data + some other data in an event handler, > you'll need a different approach, because deref will only return the > underlying app-state values. > > > On Saturday, November 8, 2014 10:39:49 AM UTC-6, Colin Yates wrote: > > 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" <jack.jack...@gmail.com> 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 > > clojurescrip...@googlegroups.com. > > > > To post to this group, send email to clojur...@googlegroups.com. > > > > 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 clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.