Tying to dom elements sounds reasonable to me. You mean DOMNodeRemoved? There's such as a thing in the spec but do the browsers, especially everybody's favorite trouble maker, IE, support it? See http://en.wikipedia.org/wiki/DOM_events, http://stackoverflow.com/questions/3750546/event-observe-domnoderemoved-does-not-work-in-ie and http://www.bennadel.com/blog/1623-Ask-Ben-Detecting-When-DOM-Elements-Have-Been-Removed-With-jQuery.htm.
Kalle On Sun, Jun 19, 2011 at 12:03 PM, Howard Lewis Ship <hls...@gmail.com> wrote: > I've been, effectively, prototyping a client-side pub/sub solution for > Tapestry with one of my client projects. > > The goal is to reduce the abuse of DOM events or other complicated > structure. If two components need to work together when they are both > present in the page, it can be difficult to orchestrate when those > components render at different times (due to Ajax) or are nested > within other components (making it hard to obtain a client-side id to > work with). Having behaviors loosely coupled, using well-known topic > names, is a major part of the solution for this. > > Topics names are of the form "tapestry:zone-updated/myZoneId" or > "app:master-category-changed". The convention I'm coming up with is > that topic names start with a prefix ("tapestry:" for the framework, > or "app:" for the application), then a name, then optionally a > client-element id. > > Message publication is by topic name, and there's a bubbling system: a > message published to "foo/bar" can be subscribed to with "foo/bar" or > "foo". This will allow, for example, code to be aware of any form > that's about to submit, or any Zone that's about to update, etc. > > The topic message payload (or just "message") is any JavaScript > object, defined by the code that publishes to the topic. It is passed > to any listener functions listening to the topic. > > Part of the code is in 5.3.0, part of it is evolving inside my client > project and will be merged into 5.3.x. > > In any case, lots of it is working out nicely. I have some very > sophisticated logic on the client side and the pubsub system makes > things possible that otherwise would not be. > > However, I do have a concern. Although its easy for a listener to > unsubscribe itself, what I'm struggling with is when a topic is > associated with a DOM element (which is often the case). I would like > to have a means of recognizing that a DOM element (or tree of DOM > elements) has been removed from the DOM, and to automatically destroy > topic publishers and listeners related to that DOM element. > > Failure to do this will likely result in memory leaks inside > long-running pages, and potentially to client-side exceptions as > listeners perform updates to DOM elements that are no longer attached > to the document. > > One option I'm considering is to make topic names simple strings, but > to always associate them with a DOM element. I.e.: > > var publisher = T5.createPublisher("tapestry:form-validate", myForm); > // createPublisher() returns a publisher function. > // The return value of the publisher is an array of the return values > of all listener functions. > > T5.sub({ topic: "tapestry:form-validate", element: myForm}, function() > { ... }); // to match message published for myForm > // The return value of sub() is a function used to unsubscribe the > listener function from the topic. This can be used for > // "listen once" scenarios. > > T5.sub("tapestry:form-validate", function() { ... }); // to match > messages published for any form > > var result = publisher({ foo:bar, biff:baz}); // Send the object to > listener functions > // Get back an array of return values. > > This would replace and formalize the "foo/client-id" pattern I discuss above. > > The pub/sub approach above could combine with some code that would > iterate over elements being removed form the DOM and cleanup the > publishers/listeners mappings. Part of this code already exists, to > clean things up for IE (breaking apart the DOM and JS to prevent > memory leaks). > > As I write this, I'm really liking the idea of always linking topics > to elements; listener functions could receive two parameters: the > payload message, and (second & optional) an event object that would > include, among other things, a reference to the element for the > message. > > In the larger scheme of things, appling this pub/sub structure will > have a lot of benefits. It effectively provides more "seams" on the > client-side where logic can be injected, which should lead to less > monkey-patching. I also see it as a great mechanism for dealing with > Cometd/Websockets, where the server-side can publish events to the > client-side. > > My personal plan is to start introducing the T5 namespace and pub/sub > features in 5.3 and go a bit more whole-hog in 5.4. In fact, the > "theme" of 5.4 could be JavaScript: breaking the ties on Prototype, > pub/sub, and Websocket support. > > So, I'm interested in general thoughts on the approach, and also some > insight into the memory leak issue. It would be great if there was a > bubbling DOM event that we could use for this purpose. I don't think > there is. > > -- > Howard M. Lewis Ship > > Creator of Apache Tapestry > > The source for Tapestry training, mentoring and support. Contact me to > learn how I can get you up and productive in Tapestry fast! > > (971) 678-5210 > http://howardlewisship.com > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org > For additional commands, e-mail: dev-h...@tapestry.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org