Up to part 4, I've been talking about the AdvancedDataGrid itself and the properties it has that are supposed to make your life easier, like styleFunction and iconFunction. And they do, once you understand them. But now I'd like to turn my attention to the data source I was using to drive my AdvancedDataGrid (ADG).
My AdvancedDataGrid is being used as a menu on an eLearning application. The application has various tasks that the user must complete. Once a task is complete, it is shown again in review mode, which provides the student with remediation on what he did wrong or right. The student can also view reports of what he did in a given task. So each task will be available in three modes: normal, review, and analysis. The mode will be determined by the top-level container.
To this end, I created an array of MenuContainer Value Objects (VO) that contained a number of Task VO's. I assigned these to a HeirarchicalData dataProvider in the ADG. I immediately realized that the itemClick event just gave me the Task VO, and the Task knew nothing about its parent (and rightly so). Apparently, the itemRenderer also knew nothing about where the Task fell in the data structure, nor anything else in the ADG.
I realized it was a slippery problem, since even if I were to loop through the MenuContainers and find the Task that was selected, I would only find the first instance of it. So I decided to wrap my Task class in another class that had two properties, task and UID. In this class, TaskUID, I simply used UIDUtil to create a UID for this instance of the task.
Once I had that accomplished, I decided to take one more squint at the docs before I built a function to loop through and find my TaskUID. I trolled the language reference only on the word hierarchical. I'd looked at the HierarchicalCollectionView before, but the description implies that this is for making flat collections look hierarchical (heck, it actually says it!). However, this class does include a method, getParentItem(), which looked perfect for my needs.
In a wild leap of faith, I cast the event.currentTarget.dataProvider from the itemClick event from HierarchicalData to HierarchicalCollectionView and the method worked! It gave me a reference to the MenuContainer from the TaskUID. I have no idea what the differences are between those classes, so I wouldn't guarantee all methods would work when you do this kind of casting, but this worked for me!
Musings on AdvancedDataGrid (Part 5)
english mobile
Posted by
Amy B
at
11:23 AM
1 comments
Labels: AdvancedDataGrid, Event Listeners, HierarchicalCollectionView, HierarchicalData, UIDUtil, Value Object
Order of Events for ItemRenderers
english mobileI suspect that I'll be blogging a lot about ItemRenderers, because it seems that there's a ton that can go wrong with them and lots of stuff to learn before you can get it right. A good starting point in learning about them is Alex Harui's Blog. I found this source a bit misleading in my current project, because it suggests that you should run your init code in the dataChange event listener function.
The problem I found is that the dataChange event runs before some objects in the component have been instantiated, so trying to change their attributes results in a spectacular explosion. The solution I found is to set a boolean value in the creationComplete listener to indicate whether or not the component was completely drawn, then run the same logic that would have run from the dataChange function. So when the data changes, the dataChange listener will initialize the objects, but on first creation, the creationComplete listener handles it.
I suspect this is not the optimal way to handle this, but it works and doesn't require much rocket science on my part.
Update 7/3/2008: I eventually had a series of conversations about this with Alex, and it seems that the mistake I was making was that I was trying to address objects directly in the dataChange event handler, and, as noted above that doesn't work. But instead of repeating that call in dataChange and creationComplete, what I should have done is to set a boolean flag in dataChange only to indicate that the property (which in this case was a dataProvider) needs to be set on the child object.
I was trying to avoid overriding any of the inbuilt methods, but the engineers intended for developers to override many of the methods when creating itemRenderers. In this case, I needed to override commitProperties and set the dataProvider whenever that flag was true (and then set the flag back to false, of course).
