Question

I'm using an array to populate a DataProvider, which I'm using to populate a list component. Like this:

var myDataProvider = new DataProvider(this.myArray);
this['list'].dataProvider = myDataProvider;

When changes are made to the array, I want to tell the DataProvider to update so that those changes will be reflected in the list component. It would be nice if there was a way to tell the DataProvider to listen for changes in the array and update itself, but I would settle for a way to manually update it.

I can replace the DataProvider with a new DataProvider, but then the list loses its selection. I suppose I could go through the DataProvider and compare and modify every entry to make it match the array, but this seems way too cumbersome. Is there any way to tell a DataProvider to update to match an array?

Edit: I'm looking for a way to do this in Flash, not Flex.

Was it helpful?

Solution

Arrays are not bindable in AS 3; they don't dispatch/trigger data binding events themselves.

If you are working with Flex, you can wrap your array in an ArrayCollection which is bindable, and manipulate the ArrayCollection instead of the Array, everything should automatically work as you hope.

So, in practice:

var myAC:ArrayCollection = new ArrayCollection(myArray);
var myDP = new DataProvider(myAC);

myAC[0] = 'changing the array!'; // will be reflected in the dataProvider

Better yet, if you're passing that DataProvider instance to a Flex component, you can usually (almost always) just pass the ArrayCollection instead. But, you haven't shown enough context for me to be sure on this.

Here's a few useful links:

Edit: My fault, I did indeed assume you were using Flex for the above.

In plain old AS3, the principal is the same. The Array does not dispatch events, but the DataProvider does. If you can make your changes to the dataProvider itself then you're good to go.

The AS3 DataProvider class offers a bunch of methods for data manipulation, like addItem, removeItem, replaceItem, replaceItemAt, just for example.

So, it basically comes down to what kind of changes you need to make to the source array. More often than not, you'll be able to do them via the DataProvider.

OTHER TIPS

I've spent the last 4 hours trying to figure out what the connection between a dataprovider and the original array is. I've found that using the GetItemAt method on the datagrid also updates the array that the datagrid's dataprovider is made from automatically updates when I use the GetItemAt method.

import fl.events.ListEvent;
import fl.data.DataProvider;

var arr = new Array();
arr.push ({Name:"Mike",Height:"6'4"});
arr.push ({Name:"Jackie",Height:"5'9"});
arr.push ({Name:"Mike",Height:"0'10"});

dg.addColumn("Name");
dg.addColumn("Height");
dg.dataProvider = new DataProvider(arr);
dg.addEventListener(ListEvent.ITEM_CLICK,updatename);

function updatename(e):void {
e.target.getItemAt(e.rowIndex)["Name"] = name_txt.text;
trace (arr[e.rowIndex]["Name"]);
}

What annoys me is that I use the removeItemAt method, it removes the row from the datagrid, but doesn't update the array. At the start of this project, I had no idea that getItemAt would update the array and so that's why I spent 4 hours trying to figure out how my code was subtracting twice.

Along the same lines, if you update the array, it will automatically update the datagrid (at least with Flash CS4).

import fl.events.ListEvent;
import fl.data.DataProvider;

var arr = new Array();
arr.push ({Name:"Mike",Height:"6'4"});
arr.push ({Name:"Jackie",Height:"5'9"});
arr.push ({Name:"Mike",Height:"0'10"});

dg.addColumn("Name");
dg.addColumn("Height");
dg.dataProvider = new DataProvider(arr);
dg.addEventListener(ListEvent.ITEM_CLICK,updatename);


function updatename(e):void {
    arr[e.rowIndex]["Name"] = "none";
}

However, you still can't remove a row in the array using arr.splice and have it automatically update the datagrid. For deletions(splice) and additions (push), you have to update the array and the datagrid separetly.

You can change the data and then asign the dataprovider again

var myDataProvider = new DataProvider(this.myArray);
this['list'].dataProvider = myDataProvider;

myDataProvider.getItemAt(0)["Name"] = "Some change";
this['list'].dataProvider = myDataProvider;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top