views:

61

answers:

4

My data grid is displaying stale data, rather than the real time data available in it's data provider (array collection). I've tried refeshing the data in the collection, but that has no effect. Below is my code, does anyone see what could be the problem?

<mx:Accordion/>
<fx:Script>
<![CDATA[
private var _gridData:ArrayCollecton = new ArrayCollection;
[Bindable] public function get gridData():ArrayCollection { return _gridData; }
public function set gridData(value:ArrayCollection):void { _gridData = value; }
public function loadGridData():void {

// imgCollection is the data returned from the server
var tempCollection:ArrayCollection = new ArrayCollection();
 for (var i:int = 0; i < imgCollection.length; i++)
            {
                var img:Object = new Object();
                img.id = imgCollection.getItemAt(i).imgId;
                img.url = "http://..." + imgCollection.getItemAt(i).imgId;
                img.caption = (imgCollection.getItemAt(i).imgCaption == null) ? "": imgCollection.getItemAt(i).imgCaption;
                img.group = images;
                tempCollection.addItem(new ObjectProxy(img));
            }
gridData = tempCollection;

<!-- Use http service to get data and save it in grid data array collection, this is run on accordion create completion and whenever data is added or removed from the array collection -->
}
]]>
</fx:Script>
<!-- NOTE: There is a cyclic binding between the data grid and the gridData array collection -->
<fx:Binding source="dg.dataProvider as ArrayCollection" destination="gridData"/>
...
...
<s:NavigatorContent>
<s:Panel>
<mx:DataGrid dataProvider="{gridData}" ...>
...
...
</mx:DataGrid>
</s:Panel>
</s:NavigatorContent>

UPDATE: I tried the suggestions mentioned below, however, they do not resolve the issue. The data grid has custom item renderers, could that be the problem?

<?xml version="1.0" encoding="utf-8"?>
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                          xmlns:s="library://ns.adobe.com/flex/spark" 
                          xmlns:mx="library://ns.adobe.com/flex/mx" 
                          focusEnabled="true">
    <mx:Image id="image" source="{data.url}" height="65" maintainAspectRatio="true" scaleContent="true"/>
</s:MXDataGridItemRenderer>
A: 

Have you tried rebinding the dataProvider to the DataGrid when the provider is updated?

Brian Driscoll
A: 

Hi,

If I'm not mistaking you should have [Bindable] on the setter as well because the datagrid has not other way of knowing when your data has changed.

Regards, Alin

Alin Purcaru
I'm pretty sure that would cause a compile error. You only need it once.
Wade Mueller
Placing the bindable meta-tag on the setter is viewed as redundant. However, to that end I tried using "dg.invalidateProperties()" neither worked.
tommac
A: 

Looks to me like you are overthinking this. Since you aren't doing anything in your getter/setters you could get rid of them and just mark your ArrayCollection as Bindable, then set it as the dataProvider for the DataGrid and be done:

<fx:Script>
    <![CDATA[
        [Bindable]
        public var gridData:ArrayCollecton = new ArrayCollection;

        public function loadGridData():void { 
            // Whenever you change the gridData, the DataGrid will update appropriately.
        }
    ]]>
</fx:Script>

<mx:DataGrid dataProvider="{gridData}"></mx:DataGrid>

The problem with your existing code is likely that you are not dispatching a change event in your setter. Getting rid of the getter/setters allows the ArrayCollection to handle dispatching that event for you. Hope that helps.

EDIT: Based on the updated question, you may want to try changing your renderer to look like this, which would help if your custom data object is not bindable.

<?xml version="1.0" encoding="utf-8"?>
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                          xmlns:s="library://ns.adobe.com/flex/spark" 
                          xmlns:mx="library://ns.adobe.com/flex/mx" 
                          focusEnabled="true">
<fx:Script>
    <![CDATA[
        override public function set data(value:Object):void { 
            super.data = value;
            image.source = value.url;
        }
    ]]>
</fx:Script>
    <mx:Image id="image" source="{data.url}" height="65" maintainAspectRatio="true" scaleContent="true"/>

Wade Mueller
I tried switching to: [Bindable] public var gridData:ArrayCollection = new ArrayCollection(); but that didn't resolve the issue. My data grid has custom item renderers; could that be the cause of the problem?
tommac
Possibly. How are you setting the properties in your custom renderer? Did you override the set data method?
Wade Mueller
I'm using the default 'data' property in my custom renderer; see update above.
tommac
If you are binding to the default data property, and the data object itself is not bindable, you won't see a change. (I'm assuming your data objects are some kind of custom object here.) If that's the case, you can mark your custom data object class as Bindable, or you can override the set data method on your renderer and manually set the properties on your renderer based on what gets set in your overridden set data method.
Wade Mueller
For clarification, the data objects are somewhat custom. However, if you look at "loadGridData" function the custom objects are object proxies which are then added to a bound array collection. Thus aren't the objects bound as well?
tommac
A: 

You don't need "cyclical" binding, because in your datagrid you do not change the collection, but you change its items. The collection stays intact. the dataprovider of the DataGrid and your _gridData point to the same collection.