mxml

February 11, 2008

Boo! I'm an Event Manager

For a contextual meaning of the following you’ll probably want to check out this post by Jesse Warden.

While in the course of building flex applications there almost always comes a time when events just don’t line up properly for whatever reason. For example Global Event Listeners that listen for events that reside in modules that may or may not ever get loaded. Renderers that are use in repeater/list/grid controls that may don’t define our events in their metadata. And also, events that are fired from NonVisual Components that may or may not reside in the Display List.

In all these cases, the difficulty resides in the fact that as a developer you may not have / know about the specific instance of the object you want to add your listener to. In most cases this is OK, because as long as the component is a visual component you can still capture that event by adding your listener above it and using capturing/bubbling. The backstop in this scenario is always the SystemManager where you can add listeners to. However, you have to make sure you bubble or useCapture.

In the case of Global Listeners using the SystemManager is fine. But if we’re nested in three or four screens and we want to have specific instance code run and no more, because we may have two or more instances of the same object on the screen at one time, we don’t want the event getting all the way to the SystemManager, ( and we need to remember to stop the event) A better solution would be to confine our event to specific context. A localized SystemManager of sorts. In the case of using a DataGrid custom renderer and dispatching the event we want to listen for the the event in the document that houses the DataGrid. The document object gives an instance level where we can dispatch and listen for events safely. The document object also makes sense from a coder’s point of view. If I create a Panel called MyPanel and stick a button in it that dispatches an event, and then create two or more instances of MyPanel, what we get is objects named like MyPanel0, MyPanel1, MyPanel2, etc.

To get to the basics of how and where we dispatch our events there are only a few things we need to worry about. First, there is always a point up the Application tree where our events can be captured. Thus, the listener is the only one that needs to know about where the rendezvous point is. The object doing the dispatching doesn’t need to care. The way I think about this is:

Listeners, need a rendezvous point from which they can capture the event. Dispatchers must know how to define their target.

To help me remember how to set these two events properly I created an EventManager class that hides the implementation of dispatching these events from me. I also created an AppEvent class from which I can extend my AppEvent classes. An AppEvent might be something like a UserEvent.LOGIN that is global, or might be specific to different sets of code in my app, like a ProjectEvent.PROJECT_ITEM_CHANGE event. All classes in my app can then import my EventManager class to make sure they can dispatch and subscribe to events in the context they need to.

The Signature on my Event Manager class looks like

public static function addEventListener( type:String, listener:Function, rendezvous:EventDispatcher = null, priority:int=0, useWeakReference:Boolean=true ) : void

public static function dispatchEvent(event : AppEvent, target:EventDispatcher = null ) : void

Some noticeable things about these two methods because at first look they look pretty harmless, in fact almost useless, and duplicated. First with my addEventListener, the noticeable thing is the rendezvous object that you can pass in and that defaults to Application.application. This allows you to look up and down the object chain to find the exact point where you want to add your listener. The addEventListener always uses useCapture, and the AppEvent class always bubbles so we don’t need to worry about whether the event will be caught or not. ( This is especially good for team scenarios where there’s always a fat fingered member that fancies himself a proctologist )

Second on the dispatchEvent method you’ll see that a target is allowed to get passed in ( it defaults to Application.application, which means Global) , which creates some interesting side effects and a lot of flexibility. Essentially passing in a target allows me to set the target of the event in scenarios where an event might not originate on the target. This is real handy when dispatching events that are defined off data as in ValueObjects, a good example might be when I want to dispatch that UserEvent.LOGIN event and I want my target to be a UserVO object. The actual login event might originate when the data arrives from the server with our user info. I can then propagate the UserVO throughout my system and anybody who cares can do something. Our UserVO might contain permissions and we might need to change our layout, or it might contain user preferences, etc.. 

The ability to set the target of an event is also a handy technique when using NonVisual components.  I pointed out in this article how to create a non visual component that is implemented in mxml. Jesse pointed out in his article that he’s changing his mind about using IMXMLObject, which is a fair argument, but when you think about events as Listener : Rendezvous, Event : Target and then realize you can switch out the rendezvous and target, it doesn’t take Tom Sawyer to paint the white fence white. Using our IMXMLObject and the dispatch event technique that I described above gives us the perfect vehicle to dispatch our events. IMXMLObject interface defines the following method

public function initialized(document:Object, id:String):void

We can then use the document object to dispatch our event into the proper context of where we want to dispatch it. Like I mentioned above, the document object comes in instances of objects we defined. From my previous MyPanel example, a non visual component that is implemented in mxml would get a document named something like MyPanel0 or MyPanel1. As long as we have an instance of MyPanel we can add our listeners to it.

In most cases, I just use the EventManager class to dispatch to the proper context. Rarely do I actually listen through it, but it’s there and can be handy.

I’d like to point out that this is by no means a substitute for the built in event lifecycle. It’s important to use this technique only when is necessary. And be very afraid of global events. Like most things global, Global Variables, Global Constants, Global Singletons, Global Warming, they can be very bad, if you don’t believe me, just ask him.

I’ve included a sample application demonstrating some of these techniques with links below. There’s also some more of my value object techniques I’ve been demonstrating, like setting a value object by passing in a form or xml and some other techniques that make app building simple, but I won’t get into detail on them unless someone asks or I run into one of these.

Here’s the demo:  I left traces everywhere so you can download the app and run it.

demo

source

 

 

February 07, 2008

Complex Value Objects as Data Descriptors

Regarding my post here about how to use a base value object, a reader writes:

That’s all well and good, but my data is very complex  and is returned to me in an xml hierarchy structure with nodes and subnodes etc., and while your solution allows me to easily create value objects, I still have to pull my data out of the xml so your base value object doesn’t gain me much and it’s easier to bind to xml using e4x.  

e4x does rock. I have to admit. My example was just a simple how to solution. I would never try to create a one size fits all solution, and some of your reasons validate my assumption on this:

“my data is very complex and is returned to me in an xml hierarchy”. 

Just for the record, my data is all very complex and comes from multiple data sources, such as xml, oracle, sql, webservices and the occasional flat file.  Like a lot of people I only have so much control over how the data is returned to me. But from that point on I do have control over what happens with my data, which is why I opted for using value objects instead of xml. It’s just as easy to turn xml into a value object. An example of this is below. 

Valueobject

That being shown,  I have a few more tricks to set complex data. First, in cases where you have two value objects that have a one to many relationship, it’s quite easy to pass in hierarchical data and and automatically set sub data. This can be accomplished by using getter and setter functions. Consider the following: I have a list of users, and those users have a list of roles. My UserVO looks like this:

 UserVO

I’m using a getter to make sure all my roles are properly typed. This is  really effective with xml, where as you are looping over children nodes, and you get to a subset of data, in this case <roles> it passes that node in to the roles array and the getter makes sure everything gets assembled.

The other thing that i’m doing with this UserVO is that i have two getters in here that are more about convenience than anything else. I have a label getter which I’ve already talked about here and also i have a getter named children, which represents to controls like the tree what data I want to represent the children or sub nodes. I can create a bunch UserVO’s and pass them to grids, trees, etc without worrying about what’s getting displayed by default, and if I need to I can always overwrite the label and children in the actual implementation. In essence I’m using my value objects as my Data Descriptor. I’m not sure if the flex guys had this in mind when they built the data descriptor classes, but I find for even the most complex of scenarios where I have several complex value object chains representing data, defining them this way sure does make my code alot cleaner and easier to maintain. I never have to code for different data scenarios where i might have an xmllistcollection or an array collection, I just always convert data into something I can control, which are value objects.

 

 

Here’s a quick example. As always right click for source. 

 

 

 

 

 

 

February 05, 2008

My Boring Base Value Object

After some very encouraging remarks from Ark on this post I decided to make my Titles as boring as possible so all the left brain people in the world ( read about them here ) can understand me. If you want to tune out now now I’ll understand.

Or not, I’m really just interested in blogging about technology so I’ll keep to my thought and talk about using a Base Value Object . One of the things I never do is set individual properties on objects. I should be able to pass them an object, and they should know how to set themselves. I demonstrated this with that horribly named  post here, and I wanted to follow up that post with the technique I use to create value objects.

The concept is as follows: You have a lot of different value objects and no matter what you throw at them they know how to populate themselves, so that whether it’s an object returned from the server or it’s a selectedItem from a DataGrid the call to create a new value object should be the same. for example:

var user : UserVO = new UserVO(selectedItem);

var user : UserVO = new UserVO(event.result);

 

My UserVO looks like this. Notice it passes the args to the super function, and it’s only responsibility is to define what it looks like.

public class UserVO extends ValueObject

{

public function UserVO(args:Object=null)

{

super(args);

}

public var name:String;

public var email:String;

}

And finally my Value Object that does all the work.

public class ValueObject

{

public function ValueObject(args:Object=null):void

{

setVO(args);

}

public function setVO(args:Object=null):void

{

if(args == null)

return void;

for (var key:String in args)

{

// for some reason mx_internal_uid gets in the way.

if (key != "mx_internal_uid" && this.hasOwnProperty(key))

this[key] = args[key];

}

}

}

 

My base value setVO function is where everything takes place. You can make your objects dynamic and take out the check for hasOwnProperty(). Also, Examine the type of the args passed in to the setVO function to make it possible to pass in xml, or arrays, or any other sort of data type, I took out my checks for the purpose of brevity.

Well hopefully this post was drab enough to win over Ark. If you’re still in the mood, check out this.

brian..

 

 

 

 

 

dataProvider, setForm(), or whateva

I just voted for my the bugs I'd like see fixed in for the next version of flex. If you haven’t done so you can learn more about it here. One of the bugs I did not vote for was the ability to have a data provider ( although that’s not what I’ve been calling it) for a form. Not because I think it’s a bad idea, but only because I already have a component that will do this very thing. So I threw together this app with an implementation that you’re welcome to download and use. Before I get into specifics, though, I’d like to say that I don’t think the concept of a dataProvider is appropriate, even though, apparently that’s what it’s being referred to in the bug and on flexcoders. I think what the form really needs is ability to set all the controls in it on the one side, and get all the values off the form on the other side.

Anyways, the idea behind this is simple. I implemented an interface called IFormControl that allows me easily set controls. For every form you want to include in a form you can implement the interface. I’ve implemented simple controls in my demo, and the demo is actually a very scaled down version of what I actually use. But if you want to know where you can go with it, think about what it would take to place a data grid in a form control and pull off the appropriate values. Also, think about how you would use remoting to submit the form to your server, return either a Great Success or a Great Failure.

You can view my form control demo here.

If you have any questions, feel free to email, post comments or nothing.

brian..

 

February 04, 2008

Who wants to see Non Visual Components anyways.

Or, Non Visual Action Script Components that are implemented in mxml. I have several components that I use on a day to day basis that are non visual in nature and that I want to implement in mxml. I need them to have an « id » and fire off some common events, particularly creationComplete invents. Until recently my hack had been just to extend UIComponent, but knowing this was not ideal at all for so many reasons (they would take up space on the page, doh!) I’m sure ya’ll can tell me about, I finally took the time to figure out how do create a non visual component and dispatch the proper events.

Have your object extend EventDispatcher and implement IMXMLObject. Then all you have to do is fire off the events you want when you want them. In my original use case I wanted to know the creationComplete event and so I implemented  something similar to the following, but you can add all sorts of events that you might otherwise use with mxml objects. 

 

import flash.events.EventDispatcher;

import mx.core.IMXMLObject;

import mx.events.FlexEvent;

[Event(name="creationComplete", type="mx.events.FlexEvent")]

public class NonVisualComponent extends EventDispatcher implements IMXMLObject

{

public function initialized(document:Object, id:String):void

{

this.document = document;

this.id = id;

this.dispatchEvent( new FlexEvent("creationComplete",true));

}

public function NonVisualComponent():void

{

super();

}

public var document : Object;

public var id:String;

September 25, 2007

The need for smarter flex controls.

If you saw some of the junk I have to deal with in our database you’d probably laugh, and if you didn’t it’d because you’re in the same boat as me. I constantly have to deal relational mapping or database compatiblity issues. It seems over the years, whether out of need or some sort of creative insight I apparently lack, my database forefathers have come up with the following list of things that represent a boolean.

True : 1,”A”,”YES”,”Y”,”Active”

False: 0,”I”,”No”,”N”,”Inactive”

Now, of course all those strings are not case sensitive, and are stored as such things as “Active” and “active” depending on which way the wind was blowing when the developer wrote it those many years ago. Almost always I display a boolean value as a checkbox. And so I’d like my checkbox to take all of those values, display it as either checked or unchecked and then spit out a corresponding value when I submit a form. So, if the value went in as “Y” and the user unchecked the box, I should get a “N” when I inspect the value.

 

1. I extended CheckBox

2. Created a variable called values that will house the two options that get returned  

3. Because I want to pass in something other than a boolean, I can’t override the public selected setter found in the mx.controls.checkbox. ( overloaded methods would be nice ). Instead I created a setter called checked that takes type Object, does a switch on the value and sets whether it’s selected or not and also the values array.

4. Finally I create a getter called value from which i can read the correct type. It reads from the values array, where the first index is returned on true else the second index is returned.

 

Overall, the code is fairly simple and extensible. The only reason I’m blogging about this is because I’d like this kind of functionality out of the box from the flex framework. We do alot of bait n’ switch with data. We support a huge legacy Oracle database and we don’t have much of a choice. Flex is all about the ui, should that include making it easier on the developer to create the ui.

 

I’d love to see how other people are handling these types of situations. Just as a note, before this I was running my values through a function.

 

 

// default to use 1,0

public var values : Array = [1,0];

public function set checked(value:Object):void

{

switch(value)

{

case "Y":

case "N":

this.values = ["Y","N"];

this.selected = (value == "Y") ? this.selected = true : this.selected = false;

break;

case "A":

case "I":

this.values = ["A","I"];

this.selected = (value == "A") ? this.selected = true : this.selected = false;

break;

case "Yes":

case "No":

this.values = ["Y","N"];

this.selected = (value == "Yes") ? this.selected = true : this.selected = false;

break;

case "Active":

case "InActive":

this.values = ["Active","InActive"];

this.selected = (value == "Active") ? this.selected = true : this.selected = false;

break;

case "true":

case "false":

this.values = ["true","false"];

this.selected = (value == "true") ? this.selected = true : this.selected = false;

break;

default:

this.values = [1,0];

this.selected = (value == "1") ? this.selected = true : this.selected = false;

break

}

}

public function get value():*

{

if( this.selected == true)

return values[0];

return values[1];

}

 

September 14, 2007

Sweet Flex Translations

So, imho, the flex Resource Manager is cool, I mean that with all do respect, that is if you’re down with doing a lot more work than is necessary. Who besides Java purists save thier language translations in a  (.) properties file? And why would I want to even do that? I then have to make sure I keep a common naming convention with underscores and names and also not to mention the @Resource tag. It seems like twice as much work as is needed to be done.

I think there is a need for the ResoureManager, but it’s responsibilites should only include resources such as images and sound clips. Languages should be split up. At the very least there should be an option in the flex compiler to output .properties files.

So I took the liberty of creating my components that support rutime language translation. They are not complete but if I can work them out I’ll release them along with examples and translation forms that allow translators to do thier thang. At least as a good starting point for other developers who are facing the same problem.  In fact, if anybody out there wants to start a business up that caters to translating flex applications shoot me an email and let me know.

 So here is a link to my example.

http://www.mxmvc.com/translations/SweetTranslations.html#

(right click to view source)

The logic is that there are a certain number of components such as Button, Label, Panel (as in the title) that need translations done on thier labels or titles or other fields. The components themselves know this and add thier respective property fields to a LangManager that removes all special characters and creates a key with underscores (_). Phrases without translations default to whatever was put in the property so the label=”submit” would still be a “submit” if there wasn’t a “Someta” and the language was Spanish. Translations can then be done on these phrases. This can happen at runtime, the translations should be able to be stored in a properties file, or an xml file or where it seems just about everyone stores everything: a database. There also should be a caching mechanism on the client that stores common translations so that they are readily available.

There are alot of questions to answer about this however, like what if you don’t want it managed for translations. And how much overhead will this cause when dealing with very large applications?

 

Yes I know that that the grid headers don’t translate, but they should and if anybody can help me understand why it’d greatly be apprecated. I also had to turn the creationPolicy=”all” on the tabnavigator to get them to translate. I purposedly left out the components that are doing all the work because they aren’t finished and also because I wanted you to focus on what might be: and by that I mean that if you look at the source which can be found here youll notice that the mxml implemenation of the components are in no way modified or decorated with @Resource tags. They shouldn’t have to be.

 I’m lagoing to blog more on this latter when I have more to show and maybe a better understanding of what needs to be done to make runtime dynamic translations as dynamic and feasible as possible.

flexmdi Taskbar Proof of Concept

So this is just a proof of concept that I threw together. It’s a rough implementation of the taskbar concept. This functionality is something we’ve talked about implementing although no word on a time frame yet. But if someone can grab the concept and incorporate it into the library be sure to send it our way and we’ll give credit where credit is due. What needs to be done is seamless implementation into the flexmdi library that doesn’t require all the hoops I'll now jump through for you. Not that there are alot of hoops, it’s actually quite simple.

I didn’t touch anything in the flexmdi library to create this btw. In a nutshell the logic goes as follows.

1. when a window is minimized we want to remove it from the screen and add it to the taskbar after any effect has played.

2. when a taskbar item is clicked we want to remove it from the taskbar and add it back to the screen.

To do this I'm simply capturing the window minimize event, setting visible to false, then creating a taskbar item which i then add to an array collection bound to the dataProvider of a horizontal list.

When the task bar item is clicked, I'd simply setting visible to true, then broadcasting the MDIWindow restore event.

See It In Action

View Source

 

We’re going to be working on this more in the future, so any requests and/or help is greatly appreciated. And yes I know the buttons don’t show up on restore, but since our launch of the flexmdi library we’ve got a considerable amount of requests for this to be implemented by default. So I thought I’d throw this out there for now while we work on incorporating it.

 

you can get the flexmdi framework at http://code.google.com/p/flexmdi/

 

Happy Ctrl+B