bgx:components logo
© 2004 -2005
Bernhard Gaul



Bgx Xml Serialization Classes (Flash MX 2004) : Using Recursive Cloning

Flash output

 

For general details about the XML used and binding it to a DataGrid see the DataGrid example

Why cloning?

The example above uses two main DataGrids that are bound to an Array in our deserialized sample data. Both of them have a second DataGrid associated that allows to edit the data (click on a row to edit it).

In the first example both DataGrids point to the same Array SampleData.folder[1].folder[0].page. As they both use literally the same Object any changes made on the right will immediately be reflected on the left (Note also Main DataGrid 2 will reflect those changes before clicking "Apply Changes" once because it is also bound to the same Object).

Now in many cases you would want to allow the user to make changes but only apply them to your main Object once confirmed or otherwise to cancel them.

In this case you need to create a clone of your original data when transfering DataProviders from one grid to the other.

[Another example would be that you want to insert a new Object into an Array of Objects which is based on a previous one. If you simply use:
var newObj = myArray[2];
myArray.splice(3,0,newObj);

any changes made to myArray[2] or myArray[3] will be reflected in the other one. To create a new Object that is simply based on a previous one but not the previous one itself you have to get a clone.]

The BgxDesObject class now has a powerful recursive cloning function that you can use to clone the entire object itself by simply calling instanceBgxDesObject.clone(); or to clone any other complex Object or Array that you pass like

instanceBgxDesObject.clone(instanceBgxDesObject.child[0].property);
instanceBgxDesObject.clone(dgPagesCloned.dataProvider);

You can pass either Arrays or Objects to the clone() function and it will return respectively an Array or an Object.

All Objects within the cloned Data will be of type BgxDesObject and will include automatically a reference to the respective parentNodes within the cloned data. E.g. the following

var ClonedData = SampleData.clone();
trace (ClonedData.folder[1].folder[0].parentNode.label);

will return "Tutorials & Samples".

You can also pass a reference to another Object that will become the parentNode of the cloned Object itself e.g. to link it back into a BgxDesObject, like in the example below:

SampleData.folder[1].folder[0].page = 
      SampleData.clone(dgPagesCloned.dataProvider,SampleData.folder[1].folder[0]);

trace(SampleData.folder[1].folder[0].page[0].parentNode.label);

will return "Weather webservice".

Note: As the Serialization Classes are mainly set up to deal with XML compliant data structures and to avoid entering into infinite loops that could arise if Objects cross reference each other (like e.g. the parentNode properties in instances of the BgxDesObject Class), properties of Objects which are Objects themselves will currently not be included in the clone.
E.g. a clone of the following Object

var testObj = new Object();
testObj["id"] = 1;
testObj["isNew"] = true;
testObj["name"] = "test";
testObj["dataObj"] ={val1:1,val2:2};
testObj["dataArray"] = [{val1:1,val2:2},{val1:3,val2:4}];

will not include the property dataObj.

The Code


//import the class
import bgx.BgxDesObject;

//Object to hold deserialized  sample data
var SampleData:Object;

//load xml from external file
var sampleXML:XML = new XML();
sampleXML.ignoreWhite = true;
sampleXML.onLoad = parseSampleData;
sampleXML.load("sample.xml");

//parse sample data
function parseSampleData() {
	var rootNode:XMLNode = sampleXML.firstChild;
	SampleData = new BgxDesObject();
	SampleData.xmlNode = rootNode;
	SampleData.onParsed = populateGrids;
	SampleData.parse();
}

function populateGrids(){
	//populate main DataGrids
	var pagesArray = SampleData.folder[1].folder[0].page;
	//identify the attributes that shall appear in the columns
	dgMain1.columnNames= ["label"];
	dgMain1.getColumnAt(0).headerText = "Pages";
	dgMain2.columnNames= ["label"];
	dgMain2.getColumnAt(0).headerText = "Pages";
	//lets sort the data on the page name before binding it
	pagesArray.sortOn("label");
	//bind the data
	dgMain1.dataProvider = pagesArray;
	dgMain2.dataProvider = pagesArray;
	
	//populate the DataGrid without cloning
	dgPagesNoclone.columnNames= ["label"];
	dgPagesNoclone.getColumnAt(0).headerText = "Edit Pages";
	//bind the data
	dgPagesNoclone.dataProvider = pagesArray;
	
	//create a clone of the pages Array
	var pagesArrayCloned = SampleData.clone(SampleData.folder[1].folder[0].page);
	// you could also use e.g.
	/*
	var ClonedData = SampleData.clone();
	var pagesArrayCloned = ClonedData.folder[1].folder[0].page;
	*/
	//or
	/*
	var ClonedData = SampleData.clone(SampleData.folder[1].folder[0]);
	var pagesArrayCloned = ClonedData.page;
	*/
	//or you could create a separate Object as clone utility to handle all your cloning
	/*
	CloneUtil:BgxDesObject = new BgxDesObject();
	var ClonedData = CloneUtil.clone(SampleData.folder[1].folder[0]);
	var pagesArrayCloned = ClonedData.page;
	*/
	
	//populate clone DataGrid
	//identify the attributes that shall appear in the columns
	dgPagesCloned.columnNames= ["label"];
	dgPagesCloned.getColumnAt(0).headerText = "Edit Pages";
	//bind the data
	dgPagesCloned.dataProvider = pagesArrayCloned;
}

btnApply.onRelease = function()
{
	//get a clone of the dgPagesCloned DataProvider instead of applying it directly
	//otherwise you create again a direct link, use SampleData.folder[1].folder[0] as
	//parent parameter to link the newly assigned Array properly into the
	//existing BgxDesObject
	SampleData.folder[1].folder[0].page = 
		SampleData.clone(dgPagesCloned.dataProvider,SampleData.folder[1].folder[0]);
	var pagesArray = SampleData.folder[1].folder[0].page;
	pagesArray.sortOn("label");
	dgMain2.dataProvider = pagesArray;
}

btnCancel.onRelease = function()
{
	var pagesArrayCloned = SampleData.clone(SampleData.folder[1].folder[0].page);
	dgPagesCloned.dataProvider = pagesArrayCloned;
}			
			
			

For further information please contact info@bgxcomponents.com.

 

BGX Serialization Classes


View the documentation

 

 

Buy now