Search code examples
apache-flexdatagriditemrendereradvanceddatagrid

Weird ItemRenderer behavior


I have a really odd issue with an ItemRenderer. I have a main.mxml container with a ViewStack. When a user logs in, the initial view contains an AdvancedDataGrid--containing some data and the ItemRenderer below--which simply displays a Delete button. When the user logs in, this AdvancedDataGrid is automatically refreshed from the database. The Delete button should be enabled or disabled based on the user's role membership.

Scenario 1 (Logging in as an admin):

  1. Admin user logs in -- datagrid view is immediately displayed and Delete button is properly enabled for every row
  2. Logout
  3. Login as a non-admin user -- Data is refreshed and all of the rows are still enabled except for one. It could be the first, second or third rows--it's completely random. It's really wierd . . .

I restart my browser and follow scenario 2 . . .

Scenario 2 (Logging in as an non-admin):

  • Non-admin user logs in -- datagrid view is immediately displayed and Delete button is properly disabled for every row
  • Logout
  • Login as a admin user -- All of the rows are still disabled except for one. It could be the first, second or third rows--it's completely random. Just the reverse of the first scenario.

INTERESTING FACT-- If I put a breakpoint in checkDeleteSecurity, it reaches it ONLY WHEN THE FIRST USER LOGS IN AND THE DATAGRID IS FIRST REFRESHED. When I logout and the next user logs in, the data grid is refreshed, but the checkDeleteSecurity breakpoint is never caught.

[Bindable]
private function checkDeleteSecurity ():Boolean
{
     return (SecurityProxy.CheckSecurity(SecurityProxy.UserName));
}

<mx:LinkButton label="Delete" click="onDeleteClick()" id="lbDelete" enabled="{checkDeleteSecurity()}"/>

Solution

  • It sounds like you might have a couple of things going on here. First, it's worth noting that ItemRenderers are re-used; in a grid (or list, etc.) containing, say, a list of ten album tracks, one row for each track, each row gets rendered properly when the list is initially created -- but when the underlying album, to extend the example, gets changed, the album-track renderers themselves will only respond automatically to the change if they're properly wired up to do so. Generally this involves overriding the setter of the data property of the renderer:

    override public function set data(value:Object):void
    {
        super.data = value;
    
        // .. Take some action
    }
    

    That's probably why your CheckSecurity method doesn't get called on data changes -- because the button's enabled property is the only way into it, and the button's already been rendered.

    Also, binding to a function has its own issues. Someone actually asked this question last night, doing something quite similar to what you're doing (setting state on a button by binding to the result of a Boolean function):

    Can I bind a Flex component property to a function?

    Hope that helps! I'll keep an eye on the thread for follow-up comments if you have any.