Projectile trajectory with Flex 4 Keyframes … REVISITED
I finally had some time to revisit this post, and with some delay, rewrite the solution without the use of Parsley framework, as one of the readers requested in the comments section. To avoid increasing the length of the old post I created this separate one.
The old domain physics code remained untouched, so whatever caveats were there in place at the time of that writing are still there. What changed?
1. LaunchBarPM migrated into LaunchBarComponent, while LaunchBar became the skin: LaunchBarComponentSkin.
2. I moved the the glue code previously handled by Parsley into a Controller class which is registering event listeners and on both TrajectoryCanvas and LaunchBarComponent (former custom managed events handled by Parsley) and forwards messages back and forth between them.
That's it! Same visual results are below, view source is enabled for the new code:
Passing complex objects via FlashVars using native JSON
As the title states, this post shows how to pass a complex object to flex via FlashVars using native JSON on both Javascript and ActionScript side. Consider the following fairly complex JavaScript object defined using literal notation:
var flashvars = {
name: "user1",
type: "2",
loggedIn: "true",
filesList: {
path: "www.files.com/files/",
files: [
{label: 'File0', name: "file0.txt"},
{label: 'File1', name: "file1.txt"},
{label: 'File2', name: "file2.txt"},
{label: 'File3', name: "file3.txt"},
{label: 'File4', name: "file4.txt"}
]
}
};
As flashvars are always treated as strings by passing the object in the above, you won't be able to access the filesList property on the flex side. There are other supported methods to get around this limitation (such as ExternalInterface calls or just passing a simple URL, and then based on that in flex make call to that URL to fetch the complex object), but they do not make the object of this post. So the other way is to use serialization (the process of transforming an Object(s)/values into a String) and deserialization (transform the string back into an Object(s)/values). The preferred string notation in JavaScript is obviously JSON. All modern browsers support native JSON, and most popular Javascript libraries makes use of it if available or implement their own support. There are 2 methods available for serialization/deserialization:
//serializer JSON.stringify(value [, replacer [, space]]) — converts an JavaScript object/value to a JSON string //deserializer JSON.parse(text [, reviver]) — converts a JSON string back to a JavaScript object/value
I am only interested in serializing the filesList property of the flashvars object since the other properties are primitives and can be passed as they are. Modified code follows:
var flashvars = {};
flashvars.name = "user1";
flashvars.type = "2";
flashvars.loggedIn = "true";
var filesList = {
path: "www.files.com/files/",
files: [
{label: 'File0', name: "file0.txt"},
{label: 'File1', name: "file1.txt"},
{label: 'File2', name: "file2.txt"},
{label: 'File3', name: "file3.txt"},
{label: 'File4', name: "file4.txt"}
]
};
var newList = JSON.stringify(filesList);
//some IE versions URLEncodes different than the other browsers
//to be on the safe side call encodeURIComponent() on the JSON encoded string
flashvars.filesList = encodeURIComponent(newList);
On the receiving flex side if you are lucky enough to target a flash player version greater or equal to 10.3, you will benefit from the native JSON support. Methods signatures are identical to their JavaScript counterparts. Code to deserialize the Object is listed below:
//get the fileList object
var files:Object = JSON.parse(parameters.filesList);
//get the files array
var list:Array = files.files;
//output content
trace("path = ", files.path);
for (var i:int = 0; i < list.length; i++)
{
trace ("list[" + i + "] = {label = " + list[i].label + ", name = " + list[i].name + "}");
}
And the trace will output:
path = www.files.com/files/
list[0] = {label = File0, name = file0.txt}
list[1] = {label = File1, name = file1.txt}
list[2] = {label = File2, name = file2.txt}
list[3] = {label = File3, name = file3.txt}
list[4] = {label = File4, name = file4.txt}
Easy as that!
P.S.
Same technique can be employed to serialize complex ActionScript objects when written to disk as SharedObject(s).


