I've been using ARP, (arp - the open source MVC framework for flash) on a large project for one of my clients Norfolk Southern, and have found that it works well but a few things I didn't like
1) The controller requires you to register all your forms with it at startup that would require commands to be processed based on forms dispatching events, sometimes your forms are not created at statup so this wouldn't work. Some have looked at autoform registration but I found that a bit clunky too.
This I don't like as a lot of my forms are loaded at runtime due to the size of the project
2) Anyone who is interested in an event raised by a form needs to subcribe to that form as an event listener
This I don't like as I often needs a more abstract or decoupled way of listening for system events, for example a status bar may display events like 'communicating with server', "logging user in', "sorting customer results' etc...
3) There is no provision in the service handling to gracefully handle a "server' down situation where the remoting gateway is either not available or the port its on does not reply (for example if you configured your application for the wrong port or ip). I found trapping the connection object on status worked in internet exploder but not in mozzila firefox.
What I ended up doing after much discussion on the ARP list and with fellow arp users was building some extensions and packaging them into an arpx package.
The main parts I've build are
arpx.control.SystemController
This class is basically a "proxy" dispatcher, anyone who needs to know about any system event will subscribe for that event with the SystemController such as "UserLoginRequest' or "loginComplete" or "ServerCommunicationStarted" etc... anyone who publishes system events will user the SystemControler too via SystemController.getInstance().dispatchEventByProxy( {type:"UserLoginRequest", target:this, data:"hello how are you?"});
If you are using an ArpForm I've included some helper methods in a base class called ArpXForm
I've found the systemController a very clean implementation for my "system" events, forms still handle user interface and control level events like 'click', 'change' etc...
arpx.ArpXForm
ArpXForm is a helper class that inherits from ArpForm, it adds a new method dispatchSystemEvent that allows you to publish events via the system controller without cluttering your form code, it also assigns the event.target automatically for you. Included in the extensions is an example, looking at arpx.examples.SystemEventTester. view.LoginForm you can see the dispatchSystemEvent used :
dispatchSystemEvent( {type:EventNames.LOGIN_COMPLETE, data:response} );
arpx.control.CommandController
The CommandController is what simplifies a lot of command/event mapping. The command controller loads a command-config.xml that contains the name of the event and the command that should be fired based on that event, you can register multuple events to fire the same command, but you can't map multiple commands to the same event. The command controller loads the XML and then registers with the system controller for each of the events it finds in the XML file. This means if you have mapped "loginUserRequest" to com.acme.command.LoginUserCommand in the xml file then when a system event it published such from a form such as a Login form :
dispatchSystemEvent( {type:EventNames.LOGIN_REQUEST});
This form is telling the system "please login the user"
so the SystemController dispatches this event, the CommandController is a listener to this event due to it being defined in the XML file and will now fire the LoginUserCommand. This means none of your views needs to be directly registered with the controller.
the xml format is simple :
<actions>
<action event="loginRequest" command="arpx.examples.SystemEventTester.command.AuthenticateUserCommand"/>
<action event="myMadeUpEVent" command="arpx.examples.SystemEventTester.command.MyMadeUpCommand"/>
</actions>
this defination states that the loginRequest event will cause the AuthneticationUserCommand to fire.
The command controller has an addition method runCommand that I borrowed from jesterXL, it allows a command to be run directly without a view firing an event. I use this quite a bit espeically for system initialization as command are not always the results of a user interface event.
I'm using the xfactor studio XPATH parsing code for the xml parsing.
One snag here is flash won't pull in the code for a class if its not directly referenced for example if you just import com.mycompany.mycomands.* and never use a class in that package the code will not be pulled into your swf file. So you either have to force an instance of the class using something like :
var a = AuthenticateUserCommand;
or you if you are an MTASC user you can use the -pack argument which will force all classes in a particular package into your swf for example
-pack com\nscorp\app\EMC\command
would force all classes in the com.nscorp.app.EMC.command package to be included in the swf. You can see an example of 'embeddeding' the class in the example :
arpx.examples.SystemEventTester.view.ApplicationForm in the forceCommandCodeImport method. I perfer using MTASC and -pack but didn't want to force all ARP users of my arp extensions to have to use MTASC.
arpx.service.ServiceDelegate
This ServiceDelegate is the base class for handling server communcation via the arp Service class, however this service delegate handles servertimeout and also publishes a few system events such as : ServerCommunicationStart, ServerCommunicationEnd and ServerCommunicationFailed. I user the first two in a status bar to show 'something" is going on, similar to how web browsers animate their status bars when they are doing something. I may extends these two system dispatch events to include the "serviceName" they are calling in the event.data field so you can display what you are doing with the server, let me know if you think that would be useful. The ServerCommunicationFailed is dispatched if the connection.onStatus function is called (called when the gateway cannot be connected) and also when the timeout has expired, by default the timeout is 30 seconds but you can change it in your ServiceDelegate implementation by called setTimeOut and passing the number of milliseconds.
The last few classes are just utility classes such as :
arpx.util.ArpResponder
(this works hand in hand with Service Delegate to handle timouts by adding a new method onGatewayOffline)
arpx.util.ClassUtilities
This class can add "classNames" to entire packages, so that you can do myObject.className to get the name of the class an object instance belongs to, I find this useful in debugging sometimes. The other method I use on this is "dumpObject" it recursively parses and object and puts the results into a string, this way you can dump the contents of a valueObject for example
trace(" my object : ' + ClassUtilities.dumpObject(myValueObject));
This is a great tool when you get an object back from the server and you want to see what is in it.
The other methods are createObjectFromString and createClassFromString which are both used by the arpx.control.CommandController to instantiate a object as a result of reading a "string" from the XML file.
arpx.examples.SystemEventTester
I created a very simple example, its basically displays a login box on the screen and allows you to login and tells you if your login is correct or not. It uses all the features of the arp extensions and I think is a good start at an example. I had planned on adding password change too and there is a command for it but I have not implemented it as I've run out of time right now.
The example uses a remoting service "AuthenticationService" I'm using the florine .NET remoting gateway for this test but would like it if someone could implement the same thing using the AMFPHP or openAMF implementation.
The example once running allows you to login with the id "test" and the password "test123" if you get it wrong is displays this in the textArea if you get it right the dialog closes and the main form displays "Mr Test User" in the top left of the screen. Its a simple example but shows the full range of validation, commands, events and the SystemController, CommandController and ServiceDelegate all working together.
I've asked Aral for an arpx area on osflash but he's pretty slammed so not sure when they will get put up so for now I'm hosting this stuff as zip files on my server, It needs some AS docs and I will do that as soon as I have time but if you get stuck feel free to contact via the comments section and I'll take it to email if necessary.
Downloads :
downdload the arpx extensions and example fla (dist folder): ( add to your classpath in the flash ide or in eclipse)
download the .net remoting service (unzip and setup a virtual directory "FluorineWeb" pointing to the fluorine.net\webapp" directory under the root of where you unzipped the file)
You will need the following libraries to use the extensions :
flash remoting classes (mx.rpc etc..)
xfactor studio classes : download here
the arp classes : download here
So installed the .net app and make sure it runs by hitting
http://127.0.0.1/FluorineWeb/gateway.aspx it doesn't need to do anything, but if you get a application not found or error then you haven't setup the .net piece properly.
Then open the fla under dist/SystemEventTester.fla and make sure your actionscript paths include the src folder and the other libraries I mentioned above and run the test fla, type "test" as the id and 'test123" as the password and you should see that you get logged in.
I will be adding my application configuration class soon but I have to refactor it to fit in with the arpx structure and some more features to the test, just need some time :)
Cheers
Grant.

Great tips.It really contains valuable information.Thanks for sharing.
Posted by: traslochi intercontinentali | November 24, 2009 at 07:17 AM