Like the dims-chan you used in your sortable.. That was where I got the idea.
So to explain a little more about the architecture...

Root creates a drag-input channel, and a (mult) over that for subcomponents to 
tap. 
The drag sources put their events on the drag-input channel, and the interested 
listeners get the events cc'd to them.  This lets any component on the page 
listen to any drag-source on the page. 
I went a step further and reasoned that sub-components would really only be 
interested in drag-events within their bounds... which led me to add a filter 
on the tap. 

So what you're saying is, if I make my filter predicate work directly with 
(om/get-state owner :bounds) then the filter would be dynamic? 
I will have to try that out. 




On Monday, January 13, 2014 1:19:45 PM UTC-8, David Nolen wrote:
> Without diving too much into your code, I don't see why you can't just have a 
> channel that communicates bound changes which you save via om.core/set-state!.
> 
> 
> David
> 
> 
> 
> 
> 
> On Mon, Jan 13, 2014 at 4:14 PM, David Pidcock <[email protected]> wrote:
> 
> 
> 
> 
>  Let me add that, profiling this in Chrome has shown a steady growth of the 
> number of ManyToManyChannel objects when I do a lot of resizing, but Garbage 
> collection does clean them up nicely.
> 
> 
> 
> 
> 
> On Monday, January 13, 2014 1:10:15 PM UTC-8, David Pidcock wrote:
> 
> > I've been playing around with Om recently, and started down a rabbithole 
> > towards a drag-drop implementation.
> 
> >
> 
> > In my (toy) application, I have a couple of lists of items which I want to 
> > drag between. Before stumbling on Om and React, I was using a 
> > goog.fx.DragListGroup, and listening to the events.  But binding data back 
> > to sub-components of the app was starting to look onerous.
> 
> 
> 
> >
> 
> > Om to the rescue!
> 
> >
> 
> > The lists are in app-state and mutations on them cascade nicely to the 
> > sub-components. Great.
> 
> >
> 
> > So my first thought was to try to integrate DragListGroup somehow (after 
> > all - that code is already written). Unfortunately, React doesn't like DOM 
> > manipulation outside it's lifecycle (it's possible, but much harder to do 
> > in idiomatic Om).
> 
> 
> 
> >
> 
> > Fortunately, David Nolen threw a sortable example together.
> 
> >
> 
> > Building on that example, I now have my "master app" component creating 
> > some core.async channels, which it then passes down to sub-components.  
> > These components can register for drag-events within their visible bounds.
> 
> 
> 
> >
> 
> > So here's my problem : when the bounds of a component change (i.e. it get's 
> > re-sized), the existing channel still only delivers events to the old 
> > bounds.
> 
> >
> 
> > I 'solved' this by untapping the old channel, creating a new channel with a 
> > filter for the new bounds and listening to it.
> 
> >
> 
> > This seems .. unwieldy.
> 
> >
> 
> > ; state is either current or previous state , depending on whether this
> 
> > ; is called from did-update or did-mount.
> 
> >
> 
> > (defn listen-bounds [owner state opts ref-node]
> 
> >   (when-let [container (om/get-node owner ref-node)]
> 
> >     (let [ dims (-> container gstyle/getSize gsize->vec)
> 
> >            disperser (disperser opts)
> 
> >            drag-chan (:drag-target-chan state)
> 
> >            new-bounds (bounds container)
> 
> >            track-fn (fn [evt] (om/set-state! owner :last-evt evt))
> 
> >            ]
> 
> >       (if (= (:bounds state) new-bounds)
> 
> >         (do
> 
> >           (if (nil? drag-chan)
> 
> >             (create-listener disperser new-bounds track-fn)
> 
> >             drag-chan)
> 
> >           )
> 
> >         (do
> 
> >           (when-not (nil? drag-chan)
> 
> >             (untap disperser drag-chan)
> 
> >             (close! drag-chan))
> 
> >
> 
> >           (om/set-state! owner :bounds new-bounds)
> 
> >           (let [new-drag-chan (create-listener disperser new-bounds 
> > track-fn)]
> 
> >              (om/set-state! owner :drag-target-chan new-drag-chan)
> 
> >             new-drag-chan)
> 
> >           )))))
> 
> >
> 
> >
> 
> >
> 
> > (defn directed-event-chan [bounds]
> 
> >   (filter>
> 
> >    (bound-filter bounds)
> 
> >    (chan)))
> 
> >
> 
> > (defn create-listener [disperser bounds f]
> 
> >   (let [drag-target-chan   (directed-event-chan bounds)]
> 
> >     (tap disperser drag-target-chan)
> 
> >     (go (while
> 
> >           (when-let [event (<! drag-target-chan)]
> 
> >             (f event)
> 
> >             event
> 
> >             )))
> 
> >     drag-target-chan
> 
> >     ))
> 
> >
> 
> >
> 
> > So two questions :
> 
> > 1.  I couldn't tell if untapping a channel also effectively closes it. Is 
> > (close! ..) necessary here?
> 
> > 2.  Is there some way to avoid this churn? Would using an atom in 
> > (directed-event-chan [@bounds] get me a dynamic filter?
> 
> >
> 
> >
> 
> > As an aside : A lot of the core-async tutorials use (go (while true ...
> 
> > I haven't gotten into the implementation, but if all channels in a go loop 
> > are closed, is that code still taking up memory somewhere?
> 
> >
> 
> > I erred on the safe side (perhaps at the expense of readability) by using
> 
> > (go (while  (when-let ... )   and returning the value of the last read from 
> > the channel. When the channel returns nil upon close, this is guaranteed to 
> > exit.
> 
> 
> 
> --
> 
> 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.

Reply via email to