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.
