Tuesday, June 26, 2012

Dealing with the MX namespace in the FX world


So one day, you decide you're not going to use an mx DataGrid, because you know it's just not necessary; all you want to do is display a list, and if you haven't heard (...if you haven't, why are you reading this article...), Spark components are all the rage. So you set up a stub project, use an s:List, set up an item renderer, fake some data, do a little style work, and it all works great. 


Then you try to integrate it into a Flex 3.5 project. You're already using the "both mx/fx" setting in the project properties, but there's a lot of files in there that were built before Spark. 


You can end up with all kind if problems:


  •  If you have any interface implementations in your top-level element (usually a Canvas or some such), suddenly the interface methods will come up as "not implemented".
  • Your style for the List won't work, any number of odd errors, like "mobile theme only" and some such appear. 
  • Namespaces will be called undeclared.
  • "Only one language may be specified" sorts of errors. 
Here's what you need to make sure of:


  • Declare your top-level mx and fx namespaces this way (you'll also need the "s" namespace for Spark components):
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
  • If you have inline style problems, this is an example of making it work. Note that I'm styling all s:List components with this, and even though the "s" namespace is declared above, you'll still need it below in the style declaration.
<fx:style>
@namespace s "library://ns.adobe.com/flex/spark";
s|List { baseColor: #e5e5e5; }
</fx:style>
  • And the big one...make sure you change the namespace of your script tags if you are seeing problems with interface implementations and whatnot.

  • <fx:script></fx:script>
That should do it, these things have solved most of problems when dealing with the mx namespace in the fx world. 

As always, thanks for visiting. 


Wednesday, June 20, 2012

Dynamic Creation of Specific Types at Runtime in ActionScript 3

I've seen this problem bandied about quite a bit; how do I create an instance of a given type directly from the Class, without having to declare an instance of the type somewhere to force the import?

Here's how I do it:

I take an incoming string specifying a key in an object I've created; these keys maps to Class types. I then process the class type based on the key; the trick is using getQualifiedClassName, which gets the absolute namespace, which avoids having to do the instance declaration. You could technically create that myTypes object by going through the app domain, but my need is generally satisfied by just making a table of the types available this way.

I then create the new instance and return it. It's typed as "*", but that's to be expected since I can be returning almost anything. You could always return something like { type : myType, instance : newInstance } or something if you wanted to be able to maintain the incoming typeName arg, and of course you can get that info after the fact by inspecting the returned object.

private var _myTypes : Object = { "MyType1" : MyType1, "MyType2" : MyType2 };
private function createInstance ( typeName ) : *
{
     var getType : String = flash.utils.getQualifiedClassName ( _myTypes [ typeName ] );
     var desiredClass : Class = flash.utils.getDefinitionByName ( typeName ) as Class;
     var newInstance : * = new desiredClass ( );

     return newInstance;
}