SteveEisner
9 Feb 2007, 2:13 PM
Jack, now that I'm deep in the YUI / ext model of development, I've seen a certain pattern emerge that I think follows from your initial example source. It's been a bit hazardous to implement so I thought I'd suggest some possible improvements to make things easier for everyone.
Since the typical "enlightened" web app now starts with raw HTML and contributes JS behaviors, we all probably have the same loop: an "App.init" call which triggers on document ready. This uses getEl() and getEls() to hook up the various on-clicks, etc. to the existing HTML.
The problem occurs when you want to make an AJAX callback to retrieve HTML, rather than JS/XML data for existing DOM elements. In this case, the HTML you've pulled in did not exist at init() time, so it arrives with no behaviors and never gets hooked up.
To fix this I've overloaded your Element.load() function with one of my own, which on successful load calls a "subset-init" function. Inside the subset init function I use el.select('...') to search within the newly loaded element and hook up the standard behaviors. And then at document init time I call that same function with document.body, so the hookup code is shared. [I also introduced a queue to prevent load() from making too many simultaneous callbacks, but that's another discussion]
There are a couple issues I've encountered (in 0.33 btw)
1) el.select('#whatever') finds #whatever even if it's not under the element. In that case, if that's executed in subset-init then it's possible for multiple handlers to be added to the same element, which will often break things. I dunno, this might be fixed by DomQuery, since I'm using cssquery.js right now in 0.33.
2) el.select('.whatever') done in the subset-init regularly returns me a doubled list. In other words, it contains (elA,elB,elC,elA,elB,elC). So again, if I do el.select('.whatever').on('click',...) I will end up attaching the same function twice. I've solved this by wrapping up a function that first does removeAllListeners() and then on(), but it might be another cssquery bug. I'll try again with DomQuery. Or this might have something to do with it being so soon after a mass DOM insertion, etc.
3) It would be nice to add this subset-init function as a property to load() and update(), to avoid having to wrap those functions (though as I said, I've wrapped it with a queue for max load requests as well. I could send you the efficient queue implementation if you want)
4) Longer term, I could see a managed handler for behaviors in which you register a series of {CSS select + event + function } and the system will make sure that any new nodes that are added will be hooked up correctly. This might apply to other things like KeyMaps, etc.
Just thought I'd throw that out there!
Thanks again for an excellent library -
Steve
Since the typical "enlightened" web app now starts with raw HTML and contributes JS behaviors, we all probably have the same loop: an "App.init" call which triggers on document ready. This uses getEl() and getEls() to hook up the various on-clicks, etc. to the existing HTML.
The problem occurs when you want to make an AJAX callback to retrieve HTML, rather than JS/XML data for existing DOM elements. In this case, the HTML you've pulled in did not exist at init() time, so it arrives with no behaviors and never gets hooked up.
To fix this I've overloaded your Element.load() function with one of my own, which on successful load calls a "subset-init" function. Inside the subset init function I use el.select('...') to search within the newly loaded element and hook up the standard behaviors. And then at document init time I call that same function with document.body, so the hookup code is shared. [I also introduced a queue to prevent load() from making too many simultaneous callbacks, but that's another discussion]
There are a couple issues I've encountered (in 0.33 btw)
1) el.select('#whatever') finds #whatever even if it's not under the element. In that case, if that's executed in subset-init then it's possible for multiple handlers to be added to the same element, which will often break things. I dunno, this might be fixed by DomQuery, since I'm using cssquery.js right now in 0.33.
2) el.select('.whatever') done in the subset-init regularly returns me a doubled list. In other words, it contains (elA,elB,elC,elA,elB,elC). So again, if I do el.select('.whatever').on('click',...) I will end up attaching the same function twice. I've solved this by wrapping up a function that first does removeAllListeners() and then on(), but it might be another cssquery bug. I'll try again with DomQuery. Or this might have something to do with it being so soon after a mass DOM insertion, etc.
3) It would be nice to add this subset-init function as a property to load() and update(), to avoid having to wrap those functions (though as I said, I've wrapped it with a queue for max load requests as well. I could send you the efficient queue implementation if you want)
4) Longer term, I could see a managed handler for behaviors in which you register a series of {CSS select + event + function } and the system will make sure that any new nodes that are added will be hooked up correctly. This might apply to other things like KeyMaps, etc.
Just thought I'd throw that out there!
Thanks again for an excellent library -
Steve