Problem converting Array to Arraylist for dataProvider - apache-flex

private var MealsListResult:ArrayList = new ArrayList;
protected var _data:resultData = new resultData;
private function resultHandler():void
{
var Meals:Array = _data.Meals;
MealsListResult = _data.Meals as ArrayList;
MealDataGrid.dataProvider = Meals;
MealListView.dataProvider = MealsListResult;
}
Should this be working? the MealDataGrid is populating based on the array, but I am debugging and MealsListResult is null. but _data.Meals is not and I dunno if I'm missing something simple.
I can get it to work by doing it like: var MealsListResult2:ArrayList = new ArrayList(Meals); but I feel as though the first method should be working as well!
(there's mxml list and datagrid and such not shown here of course)

if _data.Meals is its runtime type is an array then _data.Meals as ArrayCollection will failed. but, new ArrayCollection(_data.Meals as Array) will working fine.
CMIIW
i guess your problem is you can't use single object as 2 or more different ui dataprovider.
try to use
MealDataGrid.dataProvider = _data.Meals;
MealListView.dataProvider = ObjectUtils.clone(_data.Meals);
UPDATE:
sorry i miss readed, i though it was ArrayColletion. but all you need to do is the same like ArrayCollection

Related

HierarchicalCollectionView: One time sort?

I have an AdvancedDataGrid that relies on a HierarchicalCollectionView as it's dataProvider. What I'd like to do is sort the data when it is first loaded, but then disable the sort so that anything that is added after the initial load doesn't cause the grid to auto-sort again. I tried something like this:
this._myDataProvider = new HierarchicalCollectionView(
new HierarchicalData(this._model.rootTasks));
var mySort:Sort = new Sort();
mySort.fields = [new SortField("startDate")];
this._tasksDataProvider.sort = taskSorting;
this._tasksDataProvider.refresh();
this._tasksDataProvider.sort = null;
But setting the sort to null just leaves the data unsorted. I guess what I'm asking is: how can I sort the underlying hierarchical data since it seems setting the sort property will keep it dynamically sorting. Thanks for any help you can provide.
Personally, I would change the sort order when you're getting the data. Either it's done on the server side or when you parse the data (ie. in your model). You can do a one time sort using Array with sortOn.
you can
1. sort the original data with sort function,
2. clone content and put it to a new collection with no sort (be careful do and make a manual clone),
3. just use the new data collection.
I had the same kind of problem until I realized that the sorting with Sort object does not change the "physical" ordering of the items within the Collection, so when you remove the Sort, the next refresh reverts the view to the actual "physical" ordering.
Similarily as stated above, I solved by it by cloning the sub-collections into sorted order this way:
public static function buildPositionSort():Sort
{
var dataSortField:SortField = new SortField();
dataSortField.name = "position";
dataSortField.numeric = true;
dataSortField.descending = false;
var sort:Sort = new Sort();
sort.fields = [ dataSortField ];
return sort;
}
/**
* This method is used to create a clone of ArrayCollection, because sorting does not
* actually change the physical ordering of the items.
*/
public static function createSortedArrayCollectionCopy(source:ArrayCollection):ArrayCollection
{
var target:ArrayCollection = new ArrayCollection();
source.sort = buildPositionSort();
source.refresh();
for each (var item:Object in source)
{
if (item.children != null) item.children = createSortedArrayCollectionCopy(item.children);
target.addItem(item);
}
return target;
}

datagrid cannot be found

I create each datagrid to be added to the NavigatorConent(), however, how do I retrieve the datagrid by ID so that I can point the ArrayCollection to datagrid's dataprovider?
private var pdg:String;
private function stabAdd():void {
var dg1:DataGrid = new DataGrid();
var cn:NavigatorContent = new NavigatorContent();
stab.addElement(cn);
cn.name = "nc"+nu;
dg1.id = "nc"+nu;
pdg = dg1.id;
dg1.addEventListener(MouseEvent.CLICK,cc);
nu++;
This will throw an error which pdg cannot be found, I wonder why:
trace(DataGrid(pdg));
The purpose of nu++ is to assign a
unique name (dg1, dg2, etc) to each
datagrid so that I can assign AC to
that datagrid's dataprovider
I can respect the need to give every component a unique name. The appropriate way to do that in ActionScript is not to specify the id/name field of the component, but rather to create an instance of the component as a variable. Something like this:
protected var myGrid : DataGrid;
And you can now access myGrid anywhere in the component, or in it's children, without creating some complicated scheme. If you need multiple DataGrid's you can store them in an array:
protected var myGridArray : Array = new Array();
And somewhere later in your code--probably createChildren() do something like this:
loop
var newGrid : DataGrid = new DataGrid()
myGridArray.push(newGrid);
end loop
For the most part, this is how all the Flex list based components do it with itemRenderers. They have an array of visible renderers.
As stated in #J_A_X_ comments, you are trying to convert pdg--a string--into a DataGrid. I would expect that to return a null value, as Flex casts tend to fail quietly.
If you want more help, you'll have to tell us the explicit error that you're receiving, possibly with line numbers and more code.

Object to arraycollection then to datagrid

Say, linedataColl is an AC that contains 200+ of rows extract from CSV and in my design, I wish to additem into SuperDataCollection object by object but the only problem was I'm unable to see any data display in "S" which is a datagrid. What wrong with my code?
var superDataCollection:ArrayCollection = new ArrayCollection();
var dc:ArrayCollection = new ArrayCollection();
var di:Object = new Object();
for(var aa:int=0; aa<5;aa++){
di.username = linedataColl[aa].username;
di.email = linedataColl[aa].email;
dc.addItem(di);
superDataCollection.addItem(dc);
s.dataProvider = dc;
}
Don't set the dataProvider within the for loop. You only need to set it once, and the datagrid will detect changes to the ArrayCollection you specify as a dataProvider.
The best thing to do is set it after you completely build up the ArrayCollection 'dc'.
Perhaps your problem will be fixed by this...
}
s.dataProvider = dc;

Non-null variable is being called null?

protected var categoryXML:XML;
protected var categoryArr:ArrayCollection;
protected var categoryList:IList;
for (var i:int=0;i<getLength(categoryXML.category);i++) {
trace(categoryXML.category[i].name);
categoryArr[i] = categoryXML.category[i].name;
}
I'm having trouble with this bit of code...
The trace here works great, and I get the response I expect, but when I try to add it to the categoryArr variable, I get yelled at and told it's null.
What could cause the difference here?
Thanks!
did you try to create your ArrayCollection : categoryArr = new ArrayCollection(); ?
So, if you are getting that there is a null reference at that line, it is because categoryArr is probably null. You need to initialize it, like #www0x0k suggested.
I will also suggest that you probably don't want to use indexes in this way. It assumes too much about the length of the particular ArrayCollection without any bounds checking. Consider code like this instead:
categoryArr = new ArrayCollection();
for each(var category in categoryXML.category) {
trace(category.name);
categoryArr.addItem(category.name);
}

Unwanted binding

The situation is simple. I have a datagrid that gets its data from a webservice.
When data from the webservice is retrived it calls the following function:
private function onListReg():void
{
arrRegOld = WSAutoreg.list.lastResult as ArrayCollection;
arrReg = WSAutoreg.list.lastResult as ArrayCollection;
dgReg.dataProvider = autoreglist;
}
dgReg is the Datagrid. the arr variables are ArrayCollections defined like so:
private var arrRegOld:ArrayCollection = new ArrayCollection;
[Bindable]
private var arrReg:ArrayCollection = new ArrayCollection;
The intent is when I hit a update button, it compares arrRegOld with arrReg and see if any values have changes. The problem is whenever I change values on the Datagrid it changes on both the dataProvider and on both ArrayCollections.
Does anyone know why is this happening? What should I do so that the binding applies only to one ArrayCollection?
Appreciate any tip.
- Mike
Your lists are sharing the same objects, if you modify the first element from arrReg you will see the modification also in arrRegOld - it is not related to binding. You need to clone the objects. You have several choices:
a) Implement a clone method for your objects (recommended)
b) Use a generic method like this one:
private function clone(source:Object):*
{
var array:ByteArray=new ByteArray();
array.writeObject(source);
array.position=0;
return(array.readObject());
}
and call arrRegOld = clone (arrReg); after arrReg = WSAutoreg.list.lastResult as ArrayCollection;

Resources