|
|
|
Move from BugDB issue number 204337
[Michael Labriola 4/29/07] Entered Bug.
While I am sure you have this same knowledge, if you would like to get a list of areas I needed to 'touch' to support this on my own, I will be happy to provide. [brbaker 4/30/07] Sending to QRB [laupark 5/4/07] PFR to Alex - Recommendation? I don't want to build this into DataGridColumn. To me, it isn't worth checking as to whether we have to parse the a.b.c expression as we'd pass through that code alot.
I have an example on my blog of itemrenderer/datagridcolumn pairs that do this. We could clean them up and provide as an example. We could officially ship them, but I don't think that's worth it either Closing as deferred. I filed a sub task to clean up and doc. what Alex suggested.
You guys really need to start thinking about Flex from an enterprise level and not a 2 page app. If an app has 800-900 datagrids to display data, do you really think it is a great solution to add custom labelFunction to each of these.
I absolutely agree with Michael. In real enterprise applications it is very common to have complex paths for a dataField (if you use something like Hibernate to manage DB data and exchange it between the client and the server, you know that you have nearly always complex data paths). It is not practical thinking about adding a custom labelFunction for each DataGridColumn. I extended the DataGridColumn class to obtain the desired result, but it should be a standard feature of the SDK.
For the record, I can't think of an efficient way to evaluate a.b.c at runtime, so labelFunction will always be faster. If you can think of an efficient way to handle sub-property fetching declaratively, please add to the comments
I agree with Michael/Andrea. If you want to keep the "pure" classes efficient, that's fine. You can subclass them and make the Enterprise-grade versions.
Alex, I'm not sure about efficiency, but (with the error checking and special code removed) here's a common override for a custom grid column ... override public function itemToLabel(data:Object):String { if (dataField.indexOf(".") == -1) return super.itemToLabel(data); var fields:Array = dataField.split("."); var endpointData:Object = data; for each(var field:String in fields) endpointData = endpointData[field]; return endpointData.toString(); } With so many other user interface elements supporting the complex pathing, this one really should, too. Efficiency of coding time is often more important than efficiency of code execution with today's computers! Hoping that complex data paths access through dataField will be a standard feature provided by the SDK in the future, I decided to keep all simple and avoid touching the internals of DataGrid or DataGridColumn overriding too many functions or creating complex behaviors. So I extended DataGridColumn just providing my own labelFunction in the following way (I put some dots at the beginning of the lines to keep the indentation right while rendering to HTML in a comment, hoping that it will work):
public class ExDataGridColumn extends DataGridColumn { .. protected var _exDataField: String = ""; .. protected var _propertiesArray: Array = null; [...] .. public function get exDataField(): String .. { .... return _exDataField; .. } .. public function set exDataField(value: String): void .. { .... if (value != null && value != "") .... { .... _exDataField = value; .... _propertiesArray = _exDataField.split("."); .... } .. } [...] .. protected function internalLabelFunction(paramItem: Object, .... paramColumn: DataGridColumn): String .. { .... if (_propertiesArray != null && _propertiesArray.length > 0) .... { .... var result: Object = getPropertyChainValue( ...... paramItem, _propertiesArray); .... return (result != null ? String(result) : ""); .... } .... return (paramItem != null ? String(paramItem) : ""); .. } .. override public function get labelFunction(): Function .. { .... return (super.labelFunction == null ? internalLabelFunction : ...... super.labelFunction); .. } [...] .. public static function getPropertyChainValue(objectInstance: Object, .... propertyChain: Array): Object .. { .... if (propertyChain == null || propertyChain.length == 0) return null; .... var returnValue: Object = objectInstance; .... for each (var propertyName: String in propertyChain) .... { ...... if (returnValue == null || ........ (returnValue is Number && isNaN(returnValue as Number))) ...... { ........ return null; ...... } ...... returnValue = returnValue[propertyName]; .... } .... return returnValue; .. } [...] } Unfortunately dataField is declared as a public variable in DataGridColumn so I cannot override it (I think that public or protected properties should always be declared through a getter and a setter function to give the developers full control while extending a class of the SDK). Instead I introduced a new property called exDataField. In the setter of exDataField I split the value in a property chain array, so I do it only one time when the exDataField is set. I overridden only the getter of labelFunction to return my internalLabelFunction only if a labelFunction is not set explicitly for an instance of ExDataGridColumn. In my internalLabelFunction I return the value of the property chain through the getPropertyChainValue function. Obviously this is just an example that works for me that could certainly be improved. I also provided my own sortCompareFunction in ExDataGridColumn to avoid those annoying runtime errors thrown while sorting a column that contains some null values that were introduced with the hotfix 2 or 3 of Flex 2.0.1, but that's another topic... I agree with Bill about coding efficiency. I started specifying label functions for every DataGrid, then I quickly realized that it wasn't really practical when you have to do it hundreds times! If my customers need a functionality in my application, I cannot say: "hey, providing you that functionality makes my code less efficient". They just need it and I have to find a way to give them what they want. Of course the Flex Team has many many things to work on, but please, think about us poor developers trying to make our software work as expected in the least possible amount of time. I count on you Flex Team! :) Has this a standard feature now in Flex 3, or do the same problems exist? And is this an issue with the AdvancedDataGrid also?
Thanks Mark Mark, unfortunately the problem is still there in Flex 3 and also in the AdvancedDataGrid.
It's sad to read that Adobe does not consider this as something worth fixing. This is basic functionality that the majority of view rendering technology used in enterprise app development supports. In a time when web app frameworks are evolving based around less boilerplate/configuration, seeing Adobe take the opposite stance on this is disheartening.
I agree with Michael/Andrea/Bill that this is a valuable feature. I haven't seen any response from Alex about the expected performance of Bill's proposed solution; if the Adobe team tried it and other solutions and found the performance to be unacceptable, then so be it, but that should be documented here in the JIRA. And if they didn't try the solution, then that's a really unfortunate lack of responsiveness on the part of the Adobe team to the needs of real-world apps. Flat objects/XML is a nice luxury when you have it, but the more complex the application, the less likely you are to have that, and the use of technologies such as BlazeDS to pass objects from the backend as objects rather than serialized XML only serves to increase the odds of situations such as this.
I figured out a way to extend the DataGrid and add support for nested data. Hopefully this solution could help in a newer version of Flex. At least now, it can serve as a workaround. <a href="http://natescodevault.com/?p=61">NestedDataGrid</a>
This issue is also larger than it seems so be cautious. It is easy to fix the output portion, but when itemEditors are used you also need to handle the commit of data back to the dataProvider. Have this all working and hope to submit a full patch soon.
I think Alex and the team need to rally behind Michael's suggestion from 2007. What is the point of using LCDS, Hibernate, and RTMP to bind data to a neutered DataGrid? I'm using Nate's NestedDataGrid and it's great, but why should a mature platform like Flex require third party components for features people need on Day One of their applications? It doesn't appear Nate's solution allows editing and commit() for nested data.
Confirmed working fine in 3.4.0.6875. Thanks for the patch!
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Milestone = M3_Moxie
Build ID = 25200
Build = 165218_flex_M1_Alpha
Fix Build ID = null
Fix Build = null