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;
}

Thursday, April 26, 2012

"JavaScript Patterns" Sandbox Pattern Correction

More from the JS world; I've been evaluating some ways to simplify the ponderous namespace typing in my javascript framework. It would appear, at this point, that the leading way to do this is by using the Sandbox pattern. As I understand it, the pattern is heavily used by the Yahoo YUI guys. It provides some other interesting capability as well, such as being able to create separate "app domains" as it were, that use different modules based on what you feed the Sandbox constructor. These different sandbox domains can be nested, etc. It's truly a plumbing pattern that seems to have a lot of potential to make your app more flexible and modular, as well as making the code easier to write/read.

 So far, I get it, and I believe it will be useful, but I'm still evaluating.

 I discovered that a reference implementation for the Sandbox pattern is in a book I already have; JavaScript Patterns. However, the reference pattern allows for feeding the desired modules for a given sandbox instance by a list of names, an array, or a '*' (meaning, use all available modules that have been registered with the Sandbox's static "modules" object literal).

 The problem is in the check that looks to see if you used "*".
if ( !modules || modules === '*' ) {
        modules = [ ];
        for ( i in Sandbox.modules ) {
            if ( Sandbox.modules.hasOwnProperty ( i ) ) {
                modules.push ( i );
            }
        }
    }
This causes an error, because the check will never evaluate to true; modules will never be as type "string", because earlier on it's typed as an array. So 'all available modules' will never get added to the Sandbox instance.

 The fix; add 'toString ( )' to the check (it makes sense, you're using absolute equality against '*', which is a string):
if ( !modules || modules.toString ( ) === '*' ) {
        modules = [ ];
        for ( i in Sandbox.modules ) {
            if ( Sandbox.modules.hasOwnProperty ( i ) ) {
                modules.push ( i );
            }
        }
    }
And the check will proceed as intended.

 As always, thanks for visiting.

Thursday, April 19, 2012

"setXMLFromString" Extension for EditableGrid

EditableGrid is a very useful datagrid and chart component. It's written in JS, and after the usual short wrestling match/learning curve to incorporate into my projects, which these days are very data display heavy; lots of charts, tabular data that has to be interactive, I was pleased with the usage and display results.

You can find out more about EditableGrid here:

www.editablegrid.com

However, there is, from what I can see, one major API oversight, and forgive me if it's there but I looked in docs and source and couldn't find it: you can't set the xml from a string or dom object directly. You have to either fake a url call in the loadXML api call, or some other such hacky voodoo.

So I wrote a very simple extension for EditableGrid that allows you to do it straightforwardly.

Create a javascript file, call it, "useXMLString.js". Put it in the extensions directory of your EditableGrid structure.

Put this function in it.



EditableGrid.prototype.setXMLFromString = function ( theXMLString ) {

if ( window.DOMParser )
{
var parser = new DOMParser ( );
this.xmlDoc = parser.parseFromString ( theXMLString, "application/xml" );
}
else
{
this.xmlDoc = new ActiveXObject ( "Microsoft.XMLDOM" ); // IE
this.xmlDoc.async = "false";
this.xmlDoc.loadXML ( theXMLString );
}

this.processXML ( );
this.tableLoaded ( );
}



Not much to see; I add a function to the EditableGrid prototype, use typical "browsers or IE" DOM parsing to turn the string into a DOM object, set the xmlDoc object of EditableGrid to that DOM object, then run the processXML and tableLoaded functions. This is pretty much how the usual EditableGrid.loadXML function works (you can see it in the EditableGrid source), I'm just taking out the need to use a URL.

Save it, and add it to your imports, the way you'd add any other extension to a JS component.

Now, don't call myEditableGrid.loadXML ( url ). Substitute myEditableGrid.setXMLFromString ( theXMLString ).

That's it, works like a charm. Note that you are responsible for making sure your XML string is a valid object.

As always, thanks for visiting.

Friday, February 3, 2012

JS: Why not just use [fill in name] framework?

I get this question when I discuss why I'm working on my own JS framework.

There's a lot of great frameworks out there nowadays; MooTools seems to be the emerging favorite. The PureMVC port uses it, all kinds of other component sets and whatnot seem to find it useful, so you end up installing it along with certain libraries, and so forth. Prototype, Backbone, YUI, and any number of other ones that are the thing du jour, are cropping up and so on.

I've been in development for about 20 years now. In that time, I've seen a LOT of frameworks, many of which no longer exist, and many that caused a lot of headaches in the long run, especially if community support or interest in them fizzled out.

To that end, I've decided, as a developer:

- Frameworks are a good thing as far as consistency, integration of developers into a codebase, and so forth. In fact, I have seen this benefit realized so absolutely, that there is no doubt in my mind that your typical project will benefit from at least some degree of plumbing framework.
- Frameworks can become a problematic thing if developers are allowed to work around, or abandon, the framework.
- Frameworks can be a horrible thing if you picked the wrong one, and/or your developers just stop using it because they think it's unnecessary.
- Frameworks should be unobtrusive; you should barely even know it's there if you're not using it, and it should add very little bulk to your codebase.

As a qualifier, I'm not talking about component frameworks. I'm talking about architectural frameworks.

So, I've come to believe, that along with a framework, comes the responsibility of educating your developers in it's use, and ensuring they use it. This means reviewing their code and making sure they're not cheating (e.g. instead of using a notification and/or event to exchange info, they are accessing "parent"...you see this ALL the time, "because it's easier/less/code/some-other-rookie-reason").

What's my point?

At this time, the notion of the "real" JavaScript developer, is still fairly immature. Crockford's book pretty much rules the roost as far as how to "think" in terms of JavaScript. This statement may not seem true to the Sencha engineers or Yahoo guys. But for your typical developer out there, particularly transitioning from the world of ActionScript, the path to writing solid, consistent code, and what tools to use, is unclear. Aside from JQuery for DOM manipulation, nothing is certain.

The biggest problem appears to be, the nature of JavaScript itself. It's about using functions as objects, and dynamically altering those objects to be useful in the context you need it for. Duck typing, shallow hierarchies, and such are what JavaScript is all about.

But...most developers aren't used to that, and many frameworks attempt to hide this way of thinking in favor of providing an artificial structure that "programmers" are more comfortable with, that being, classes, inheritance, interfaces, and so forth.

At this point in time, I think that's a mistake. We need to learn to think in JavaScript first, and find out how we can avoid mistakes we've made in the past with things like AS1 (excessive prototype manipulation, being dynamic to the point of being unable to tell one object from another without extensive duck typing and/or "flag programming", abuse of globals, etc.) while at the same time evolving the known patterns we're all familiar with to take advantage of strengths JavaScript offers, particularly, what exactly the power of "functions as first class", and the differences in how JavaScript resolves scope, means.

So to that end, I'm writing my own framework, with what I know about UI development and what I've observed over the years works (and doesn't), without losing site of the fundamental nature of ECMAScript development, which is different than classic OOP. Call it FOP (Function Oriented Programming), or what have you. But don't try to turn it into something it's not.

If you've concluded at this point that I'm some kind of framework hater, you're wrong. I have used PureMVC and RobotLegs extensively, have background in Cairngorm (which was never a good idea for UI dev imho) and experimented with many others. I like RobotLegs the best for one main reason; it is unobtrusive. It can live in your app and you can use it, or not use it, and easily combine it with other libraries. And it use EXTREMELY useful, and EXTREMELY powerful. This is in contrast to say, JSExt, which basically requires that you become a JSExt developer. Again, I have worked with JSExt a bit, and it's powerful and useful. If you're project is right for it, the benefit will be great. But it's hardly unobtrusive.

My indicators of success for my own framework will be:

- It should not require any other library unless that library has been proven stable for years and is in massive adoption by the community and the enterprise (e.g. JQuery, which my framework uses).
- It should be small. Very small. Hopefully, a handful of utility classes and possible a couple of prototype mods, but that's it.
- It should be powerful.
- It should foster decoupling and encapsulation of concerns.
- It should be repeatable and consistent.
- It should not hide the fundamental nature of javascript, which has nothing to do with classes as we know them.
- Other developers should find the paradigm familiar, e.g. more-or-less MVC.

So far, so good. I'm working on a very large project, currently in AS, and helping the company develop the strategy to go to JS/HTML (what many incorrectly call "an HTML5 app", which has the same meaning to me that the "Web 2.0" moniker had).

As always, thanks for visiting.

Friday, January 27, 2012

If using JQuery, Careful adding Methods to Object

This was tricky one. I've been writing a JavaScript framework based on "The Teaching of Crockford". That is, no deep heirarchies, functional inheritance, etc.

One of Crockford's utilities is this:

// enables a form of "super"
Object.method ( 'superior', function ( name ) {
var that = this, method = that [ name ];
return function ( ) {
return method.apply ( that, arguments );
};
} );

This is a way of invoking a "super" method on the 'object' that you have inherited from. I don't actually use it; I just included it as a "well, I'll probably want to do that sooner or later" sort of thing (so I slapped it in a utils.js file for the time being).

My jquery ajax calls suddenly wouldn't work. I kept getting this message:

Uncaught TypeError: Object function ( name ) {
var that = this, method = that [ name ];
return function ( ) {
return method.apply ( that, arguments );
};
} has no method 'test'

Umm...wtf? So, I had to delve deeper into it...and in the unminified version of jquery, I found on line 7763, a loop that checks for the content type of the ajax response (so the call was being made, and the response returning...it was the processing of the response that was breaking).

The function is:

// Check if we're dealing with a known content-type
if ( ct ) {
for ( type in contents ) {
alert ( type + " >> " + contents [ type ] );
if ( contents[ type ] && contents[ type ].test( ct ) ) {
dataTypes.unshift( type );
break;
}
}
}

Because I had added a function "superior" to Object, "superior" now became part of the items that the response type was being tested against. It failed ("superior" did not contain a function "test", which is in the ECMAScript.js2 file, not the jquery one, click on "test" in WebStorm and you'll see). So the ajax call failed.

Solution: initially, remove the modification to Object, which I wasn't using anyway. While I understand that I could add code to JQuery to ignore this sort of thing, modifying jquery is an iffy practice, because you may have to upgrade it, etc.

A better solution would probably be to make JQuery handle the error in the event it runs into this sort of thing.

As always, thanks for visiting.

Wednesday, January 25, 2012

JSBase Javascript Framework

So...I've undertaken the task of creating a JS framework that is:

- Based on best practices as defined by some of the luminaries I've been researching (things like modules, shallow heirarchies, etc.).
- Does not insulate the user from JS itself by providing an entirely different model for development. I guess I'd call it "unobtrusive framework" design.
- Has easy to understand, well defined domains of concern (model, view, controller, command, renderer, page...that's it, at least for now).
- "Feels" familiar to your average UI developer (meaning, employs general principals of MVC).
- Makes hierarchies explicit (as opposed to making them implied when using them). I'm probably wording that poorly, but you'll see what I mean soon.
- Can be used for typical web apps (for instance, not as massive as Ext JS, not as structureless as just scripting with JQuery).
- Uses JQuery (I mean why not. JQuery is awesome).
- And so forth.

Why go about this? I've been a UI dev for a long time, and I generally find that the lighter the framework, and the closer it is to the technology you are actually working with, the better. It's why I like things like RobotLegs in the AS world; aside from the context setup and mapping, it feels like I'm working in plain old AS 90% of the time, but there is no denying that the loosely coupled notification model it provides makes it easier to build an app that is more self documenting, modular, and maintainable. I see no reason why these concepts can't be more rigidly applied in the JS world to the same beneficial ends.

So...simple and lightweight, easily extendable, and always feels like JS, which is meant to be flexible and useful with a relatively short learning curve.

I'll post a first iteration of the basics soon.

As always, thanks for visiting.