8 Jan 2013 2:48 PM #11
- Join Date
- Feb 2009
- Vote Rating
GXT 2 did support widgets in Grids, but it came at a very high performance cost, and based in part on that cost (and in part on the GWT Cell API) we decided to remove that feature when we created GXT 3.
The map is probably the right way forward - invoking that attach code will ensure that you get all the wiring you need to get events, as you noted. You'll want to be sure to invoke that detach in all browsers - while I haven't read all of your code, I do note that this apparently will only work in IE9+. In those browsers, the memory leak being avoided is less of an issue, so this might mean that your app will leak in earlier browsers.
The idea of a Cell is that it is a faster API for building objects (via String manipulations and setting the innerHTML property directly instead of element maneuvering), and minimizes the number of event handlers that need to be wired up. Starting with your getElement().toString() (be very sure this works in all browsers! I think it may be broken in either Chrome or Firefox, at least in GWT 2.4), you do become more expensive in drawing, but if you can handle the events without attaching the code, it may still be worth it. My basic idea there would be to just keep a single instance of the widget to make drawing easy, then modify and toString() it for each row in the grid.
Then, in onBrowserEvent, figure out what event had happened in what part of the current field, and respond. Without knowing your specific case, I couldn't go into much more depth on events though - but again you might be able to use the same instance over and over, invoking highlight methods programatically, etc.
One more thought on memory leaks and detach - consider just a detach handler on the whole grid, and detach all widgets at the same time. Similiarly, detach any element with an item is removed from the store, etc. But unless you foresee the need to use this generalized approach many times, I'd strongly encourage you to solve it more specifically with specialized cells.
9 Jan 2013 6:07 AM #12
Colin, great feedback! Thanks!
I agree, the code i put up is for IE9+ browsers only based on the detach event used, which is a requirement i'm lucky enough to have. However, I like the idea of basing the detachment on the grid itself better.. that is a lot cleaner.
Even better though, the idea of never attaching the widget sounds like the best approach, and could really clean up this class. For my purposes, i need to display the widget in the cell but i only need to react to events on the cell itself after that (like 'click'). But for actual widget events, passing any events through via the cell's onBrowserEvent is a better idea (https://developers.google.com/web-to...onBrowserEvent)
Do you have any links to information on getElement().getString() not working? I can't find anything on google, except here (http://stackoverflow.com/questions/1...ernet-explorer) which gives me the impression it does work.
Last edited by mpickell; 9 Jan 2013 at 6:18 AM. Reason: additional question added
28 Jan 2013 8:14 AM #13
Based on Colin's feedback and some additional design, here is a cell widget abstract class that can be implemented. It is working well for me.
28 Jan 2013 11:26 AM #14
- Join Date
- Feb 2009
- Vote Rating
Nice post - though your syntax highligher seems to have gone a bit crazy though in the render method.
I'd add further cautions to the post/javadocs that this does *not* respect the widget lifecycle - no attach/detach, and manipulating dom elements (say in a Timer like AutoProgressBar does) will have zero effect. Note that this doesn't mean it is impossible to achieve such an effect - AutoProgressBarCell is able to do its thing without wrapping a widget.
One last remark, having only read the code briefly - it appears you are setting the ID of some elements to the context.getKey(). This key is *only* guaranteed to be unique across all cases where that particular cell is rendered in that particular cell widget - if you make two of these cells in the same Grid, for example, you will end up with two elements with each ID in each row, and they may not behave correctly as a result. The DOM is only allowed to have one element per ID, so consider prefixing those keys with something widget/column specific, or using autogenerated IDs from XDOM.getUniqueID(). Or, set class names instead, and use your querySelector call to find based on class instead.
28 Jan 2013 12:13 PM #15
Thank you, I appreciate you taking a look at it.
I double-checked the element ID comment you mentioned in my implementation, and I believe it is handled because:
- The ID of the placeholder elements are not set to context.getObject(), they are set to a unique value that is in a static field and incremented each time it is used. The XDOM call you mention would be a better value though, so i'll incorporate that.
- There is one instance of the WidgetCell per column, and the cache maps are local to that instance -- so using context.getObject() in those local cache maps (as the key) always will correctly reference the intended row relative to that column only.
- The context.getObject() is used as the key for storing the reusable fields and placeholder Ids in cache maps local to a column's instance of the WidgetCell.
Also, i updated the post per your other comments. no idea what's up with my syntax highlighter..