Simplified Cairngorm, Easy MVC for Adobe Flex
17 October 2007, 22:30, by JonLike many others, I have been struggling to fully get my head fully around the Cairngorm Micro Architecture, and even with the excellent Cairngorm Creator, I find it a little overkill for many Adobe Flex projects I am involved with, in fact, so does Steven Webster (one of the creators of Cairngorm).
So yesterday I sat in on an excellent Adobe eSeminar, presented by Tom Bray of SearcherCoders who presented an easy / simplified Model View Controller architecture based on Cairngorm.
To demonstrate the need for these frameworks, Tom started with an excellent example of an application based on a simple chat client. Inspired by his excellent Chatopica perhaps?:
- <?xml version=”1.0″ encoding=”utf-8″?>
- <mx:Application xmlns:mx=“http://www.adobe.com/2006/mxml“ layout=“vertical“>
- <mx:Script>
- <![CDATA[
- import mx.collections.ArrayCollection;
- [Bindable]
- public var rooms:ArrayCollection = new ArrayCollection( ["Flex", "Flash", "AIR", "ColdFusion" ] );
- [Bindable]
- public var users:ArrayCollection = new ArrayCollection( ["John", "Paul", "George", "Ringo" ] );
- [Bindable]
- public var currentRoom:String;
- [Bindable]
- public var messages:String = “”;
- private function joinRoom( room:String ):void
- \{
- currentRoom = room;
- views.selectedChild = chatPanel;
- \}
- private function sendMessage( message:String ):void
- \{
- messages += message + “\\n”;
- \}
- ]]>
- </mx:Script>
- <mx:ViewStack id=“views“ resizeToContent=“true“>
- <mx:Panel title=“Room List“ width=“300“ height=“400“>
- <mx:VBox width=“100%“ height=“100%“>
- <mx:List id=“roomList“ width=“100%“ height=“100%“
- borderSides=“top“ dataProvider=“\{rooms\}“/>
- <mx:Button width=“100%“ label=“Chat“ enabled=“\{roomList.selectedItem != null\}“
- click=“joinRoom(roomList.selectedItem as String)“/>
- </mx:VBox>
- </mx:Panel>
- <mx:Panel title=“Topic: \{currentRoom\}“ id=“chatPanel“ width=“500“ height=“400“>
- <mx:HBox width=“100%“ height=“100%“ paddingLeft=“10“ paddingBottom=“10“
- paddingRight=“10“ paddingTop=“10“>
- <mx:VBox width=“150“ height=“100%“>
- <mx:Label text=“User List“/>
- <mx:List width=“100%“ height=“100%“ dataProvider=“\{users\}“/>
- </mx:VBox>
- <mx:VBox width=“100%“ height=“100%“ >
- <mx:Label text=“Chat“/>
- <mx:TextArea id=“chatText“ text=“\{messages\}“
- editable=“false“ width=“100%“ height=“100%“ wordWrap=“true“/>
- <mx:HBox width=“100%“>
- <mx:TextInput id=“messageInput“ width=“100%“ minWidth=“0“/>
- <mx:Button label=“Send“ click=“sendMessage( messageInput.text )“/>
- </mx:HBox>
- </mx:VBox>
- </mx:HBox>
- </mx:Panel>
- </mx:ViewStack>
- </mx:Application>
The above example application is a classic example of how most of us start out developing in Flex, we end up putting all our properties and event handlers in the same file. This may be fine for a tiny application but if we want to scale it up we are going to run into problems.
For example, Flex offers us the ability to create a custom MXML component, that we can then reuse through our application, so as Tom showed, maybe we want to take the code that displays the Room list (above) and copy this into a separate mxml component . We can easily cut and paste the code and create a new MXML file RoomList.mxml with the following code:
- <?xml version=”1.0″ encoding=”utf-8″?>
- <mx:Panel title=“Room List“ xmlns:mx=“http://www.adobe.com/2006/mxml“ width=“300“ height=“400“>
- <mx:VBox width=“100%“ height=“100%“>
- <mx:List id=“roomList“ width=“100%“ height=“100%“
- borderSides=“top“ dataProvider=“{rooms}“/>
- <mx:Button width=“100%“ label=“Chat“ enabled=“{roomList.selectedItem != null}“
- click=“joinRoom(roomList.selectedItem as String)“/>
- </mx:VBox>
- </mx:Panel>
The problem is that we now have introduced two errors as the ArrayCollection ‘rooms’ is no longer in this mxml file then we cannot bind to it as the dataProvider for the roomList, also the event handler ‘joinRoom’ is no longer accessible. We could move these into this file, but then they couldn’t access the view stack and the problem goes on. So what we really need is to centralise our data into a central model and also centralise our even handlers into a controller.
Centralising Data into a Model
To centralise data, Tom took the Cairngorm’s modelLocator pattern, based around a singleton pattern . Where by the singleton ensures there is only ever one instance of itself, we define our Model as follows:
- package com.chatopica.chat.model
- {
- public class ChatModel
- {
- private static var instance:ChatModel;
- public function ChatModel()
- {
- if( instance != null )
- {
- throw( new Error( “there can be only one instance of ChatModel“ ) );
- }
- }
- public static function getInstance():ChatModel
- {
- if( instance == null )
- {
- instance = new ChatModel();
- }
- return instance;
- }
- }
- }
This is a typical singleton, implemented in ActionScript 3. As Tom pointed out in the eSeminar, ActionScript does not allow for private constructors, so here he is throwing an error if we try and instantiate the class and it is already instantiated. We can now access this Model anywhere in our application by simply typing
- ChatModel.getInstance()
So the next thing to do is move our ArrayCollection rooms into the Model so we end up with the following:
- package com.chatopica.chat.model
- {
- import mx.collections.ArrayCollection;
- public class ChatModel
- {
- private static var instance:ChatModel;
- [Bindable]
- public var rooms:ArrayCollection = new ArrayCollection( [ new Room("Flex"), new Room("Flash"), new Room("AIR"), new Room("ColdFusion") ] );
- public function ChatModel()
- {
- if( instance != null )
- {
- throw( new Error( “there can be only one instance of ChatModel“ ) );
- }
- }
- public static function getInstance():ChatModel
- {
- if( instance == null )
- {
- instance = new ChatModel();
- }
- return instance;
- }
- }
- }
Because our ArrayCollection is now in the Model that we can access from anywhere. We can change the mx:List ‘roomList’ in RoomList.mxml to use the rooms ArrayCollection in the Model as the dataProvider as follows:
- <mx:List id=“roomList“ width=“100%“ height=“100%“ borderSides=“top“ dataProvider=“{ChatModel.getInstance().rooms}“/>
We have now fixed the first issue but we still have the issue of the click handler for the button being inaccessible. We can solve this by centralising our events into a Controller
Centralising Events into a Controller
As with many event driven languages, ActionScript has a handy feature known as event bubbling. When an event is fired in a container, if the event has been set to bubble (by default events don’t bubble) it will also fire on it’s parent container, and in turn fire on the grandparent container all the way up to the main Application MXML class. By bubbling events, we can register event listeners on the System Manager and listen for any global application events that are set to bubble. So we can dispatch an event anywhere in our application using the following, and we can listen for it on the System Manager:
- dispatchEvent(new Event(‘myEvent‘, true))
Note: We have set the second parameter (bubbles) on the Event constructor to true, which tells the event dispatcher to bubble this event.
As we are centralising our events we may need to send related information along with the event, for use by the event handler. For example, as the event handler is no longer able to directly query the roomList, to see which item has been selected (i.e. roomList.selectedItem), we need to send this information with the event. We can easily do this by creating a custom event that extends the Event class as follows:
- package com.chatopica.chat.events
- {
- import com.chatopica.chat.model.Room;
- import flash.events.Event;
- public class JoinRoomEvent extends Event
- {
- public static const JOIN:String = “joinRoom“;
- public var room:Room;
- public function JoinRoomEvent( room:Room )
- {
- super( JOIN, true );
- this.room = room;
- }
- }
- }
Above we have simply extended the event using inheritance and have added a public property called room (of type Room, Tom has created a Room class that holds the name as well as a collection of Users). We have also declared the event name/type as a constant JOIN = “joinRoom”. This allows us to reference this event anywhere. In our constructor, we call the constructor on the parent class (Event) setting the event name/type to “joinRoom” and stating that it should bubble (like this we don’t have to specify that it bubbles when we create a new JoinRoomEvent). We then set the room property from the parameter passed to the constructor.
So now we can fire a JoinRoomEvent anywhere in our application, passing in a room object. The event handler listening for this event will have access to this room object. So we can fix the last error in RoomList.mxml as follows:
- <mx:Button width=“100%“ label=“Chat“ enabled=“{roomList.selectedItem != null}“
- click=“dispatchEvent( new JoinRoomEvent( roomList.selectedItem as Room ) )“/>
So far we have created a custom event and we have discussed where to look to find bubbling events but we have not looked at how to do this.
The Controller
As I mentioned before, we can listen to all events that have been set to bubble on the systemManager and as UIComponent (anyone who has created a custom component will know this one) has a reference to systemManager within it, we can extend this class. The other benefit of extending UIComponent for our class that will be our central event handler or Controller is that we can then use it in MXML.
We extend the UIComponent as follows:
- package com.chatopica.chat.controller
- {
- import com.chatopica.chat.events.JoinRoomEvent;
- import com.chatopica.chat.events.SendMessageEvent;
- import com.chatopica.chat.model.ChatModel;
- import flash.events.Event;
- import mx.core.UIComponent;
- import mx.events.FlexEvent;
- public class ChatController extends UIComponent
- {
- public function ChatController()
- {
- addEventListener( FlexEvent.CREATION_COMPLETE, setupEventListeners );
- }
- private function setupEventListeners( event:Event ):void
- {
- systemManager.addEventListener( JoinRoomEvent.JOIN, handle_joinRoom );
- }
- private function handle_joinRoom( event:JoinRoomEvent ):void
- {
- ChatModel.getInstance().currentActivity = ChatModel.VIEWING_CHAT;
- }
- }
- }
Note:: Above we have not directly added an event listener to the systemManager in the ChatController constructor. In fact we can’t to do this, because at the time the class is instantiated the systemManager is not initialised and is Null. We would therefore be adding an event listener to nothing. We get around this by adding an event listener for the global FlexEvent.CREATION_COMPLETE event, and at that point we can then add our event handler(s) to the systemManager.
Controlling the View Stack
The final thing we have left to achieve is the ability to change the View Stack from the controller, we first need to store the currentActivity or state in the Model as follows:
- public static const VIEWING_CHAT:String = “viewingChat“;
- public static const VIEWING_ROOMS:String = “viewingRooms“;
- [Bindable]
- public var currentActivity:String;
In addition to the currentActivity property above, we have also added a constant value for each state. Unfortunately it is not as simple as binding this property to the mx:ViewStack, but that does not mean it isn’t easy. All we have to use is the ChangeWatcher class that monitors a property and fires and event when it changes. We do this in the file MainView.mxml that holds out viewstack as follows:
- <?xml version=”1.0″ encoding=”utf-8″?>
- <mx:ViewStack xmlns:mx=“http://www.adobe.com/2006/mxml“ resizeToContent=“true“ xmlns:views=“com.chatopica.chat.views.“>
- <mx:Script>
- <![CDATA[
- import mx.events.PropertyChangeEvent;
- import mx.binding.utils.ChangeWatcher;
- import com.chatopica.chat.model.ChatModel;
- private var activityWatcher:ChangeWatcher = ChangeWatcher.watch( ChatModel.getInstance(), "currentActivity", handle_activityChange );
- private function handle_activityChange( event:PropertyChangeEvent ):void
- {
- if( event.newValue == ChatModel.VIEWING_CHAT )
- {
- selectedChild = chatPanel;
- }
- }
- ]]>
- </mx:Script>
- <views:RoomList/>
- </mx:ViewStack>
Now, when the value of currentActivity in the ChatModel changes, Flex will dispatch a PropertyChangedEvent. We can then listen for this event and change the view, accessing what the new value of currentActivity is in the newValue property of the PropertyChangeEvent (shown above as event.newValue).
Refactor the rest of your application…
Having done this for the RoomList component, we can now repeat the process for the code that implements the chat window. Finally we are simply left with the following in our mx:Application tags:
- <?xml version=”1.0″ encoding=”utf-8″?>
- <mx:Application xmlns:mx=“http://www.adobe.com/2006/mxml“ layout=“vertical“ xmlns:views=“com.chatopica.chat.views.“ xmlns:controller=“com.chatopica.chat.controller.*“>
- <controller:ChatController/>
- <views:MainView/>
- </mx:Application>
This process now makes our code cleaner, loosely coupled and more DRY (Don’t Repeat Yourself), easy to scale and we can reuse these components without the risk of breaking our system.
Thanks again to Tom for the excellent eSeminar which has really clarified my understanding for the necessities of using an architecture like this.
Update 23/01/08: I have added an article on scaling up EasyMVC, you can read it by clicking here.
For more information:
37 comments below:
Great summary of Tom Bray’s EasyMVC presentation. I also attended the e-seminar, but missed some of the details because of my lack of experience with Flex. Your article covered all of my questions. Thanks.
Comment by Mike@opco — 2 November 2007 @ 00:15Thanks a lot for this summary! If I remember correctly, the first versions of cairngorm relied of event bubbling too, but they decided to give up this technique because you can get stuck with it in some situations. More on this here: http://weblogs.macromedia.com/auhlmann/archives/2006/07/cairngorm_2_for.cfm
Comment by davidderaedt — 2 November 2007 @ 00:16Great post. I put a post linking to this one today on my site. I am working on getting the concept of using amfphp and getting it to work in the model. Hitting some problems but it is mostly my knowledge of action script 3 that is lacking. I do like his MVC. Thanks
Comment by Dave — 2 November 2007 @ 00:17[...] Read the rest of this great post here [...]
Pingback by chat » Simplified Cairngorm, Easy MVC for Adobe Flex — 15 November 2007 @ 04:35[...] http://clockobj.co.uk/2007/10/17/simplified-cairngorm-easy-mvc-for-adobe-flex [...]
Pingback by laflex.org » EasyMVC Transcript — 13 December 2007 @ 18:38[...] I didn’t have to do the work!
Pingback by The write-up from my EasyMVC eSeminar yesterday is now available | tombray.com - chatting about Flex & AIR — 13 December 2007 @ 21:30I just posted a sample of using easyMVC (Tom’s Version) with AMFPHP 1.9
http://themadadmin.com/wp/?p=1070
I put a link back to your writeup on easyMVC in the links section of the application.
Thanks
Dave
Comment by Dave Finnerty — 3 January 2008 @ 18:17Thanks Dave,
I have been making a great deal of use of this framework and have found it an excellent approach. I am interested in reading your article of using EasyMVC with AMFPHP.
Jon
Comment by Jon — 3 January 2008 @ 22:28Jon,
I like this system also. Keeps the code understandable and easy to update. Let me know any and all questions. I did not get to do a proper write up on the ins and out. Biggest resource is the sample code.
I did the AMFPHP code because someone asked me how to do it and a sample was easier than explaining it. Tom had answered my questions on it already.
Comment by Dave Finnerty — 13 January 2008 @ 02:20[...] http://clockobj.co.uk/2007/10/17/simplified-cairngorm-easy-mvc-for-adobe-flex [...]
Pingback by laflex.org » Blog Archive » Flex Application Frameworks — 14 January 2008 @ 19:56[...] EasyMVC is an excellent, easy to use Model View Controller architecture for Adobe Flex designed by Tom Bray from Chatopica. However as your apps grow you may find yourself outgrowing this architecture. For example as all your event handlers are centralised into one class, this class may get to large to maintain, especially as the team maintaining the app also expands.One of the best solutions I have found to handling a growing controller is to borrow the command pattern from Cairngorm which uses the Command design pattern. [...]
Pingback by Clockwork Objects » Scaling up EasyMVC as your Flex application grows (Part 1) — 21 January 2008 @ 12:14You don’t have to have your controller extend UIComponent in order to be able to declare it in MXML. Personally I’d consider not extending UIComponent because your controller really isn’t a view component. I’d pass a reference in to the systemManager and have the controller simply extend EventDispatcher in order to take care of any event dispatching needs.
Comment by Tim — 21 January 2008 @ 13:23Tim, Thank you for your alternative solution, just to clarify.
There is a good reason why Tom extends UIComponent, as he is well aware of the fact you raise. He mentioned it in his presentation, but it has slipped my mind. I think it is to do with being able to listen to the creationComplete event, as eventListeners need to be added to the systemManager at this point.
Also to clarify the controller does not dispatch any events it is purely there to listen for them.
I’ll double check with Tom…
Comment by Jon — 21 January 2008 @ 16:00I was just throwing in the EventDispatcher point in case it did need to dispatch events. I’d be interested in seeing what the arguments are for UIComponent. I still extending UIComponent is pulling in a lot of inherited code that really isn’t needed. The controller isn’t a view component. You could always pass a reference to the main view, listen for creation complete or what I’ve done in some cases is to create a public init() function which the main view could call once the creationComplete event fires. I also think it would be fine to add event listeners to the systemManager before the creationComplete event. Unless there’s some case that Tom ran into of course where this didn’t work. Is the presentation available online? Maybe I should watch it before commenting more
[...] prototypes like “WS-ThumbsGenerator”. Fore more information about easyMVC check out the excellent tutorial of Jon Baker as [...]
Pingback by WS-Blog » WS-ThumbsGenerator: Using the drag-and-drop and file system APIs with Adobes JPEGEncoder to create image thumbnails — 2 February 2008 @ 07:25[...] Click here to read an introduction on EasyMVC Click here to read Scaling up EasyMVC part 1. [...]
Pingback by Clockwork Objects » Scaling up EasyMVC as your Flex application grows (Part 2: Services) — 4 March 2008 @ 22:05Tim, To clarify why the controller uses UIComponent I have had the following back from Tom Bray: “I extend UIComponent so I can listen for the ADDED_TO_STAGE event which lets me know when the systemManager is no longer null…, the amount of code in UIComponent doesn’t concern me because it’s already linked in to the compiled SWF because everything, including mx:Application extends it, Cairngorm’s FrontController does the same thing”
Thanks for the clarification Tom!
Jon
Comment by Jon — 4 March 2008 @ 22:56Hey Jon,
These are some great examples for setting up a lightweight framework for applications utilizing the MVC pattern. Thanks for putting them out there!
However, i think it is a mistake to say that the systemManager acts the same as the FrontContoller/CairngormEvent/CairngormEventDispatcher mechanism of the Ciarngorm framework. The FrontController is not added to the display list of an application built on the Ciarngorm framework and commands are executed based on the EventDispatcher instance of the CairngormEventDispatcher (CED) delegate.
As such, since the SystemManager manages an application window, you may run into problems using EasyMVC effectively with modular Flex/AS applications and AIR applications.
That is not to say that EasyMVC does not have its place, and i would certiainly use it in some cases
Just a little info to think about prior to building modular or windowed apps. However, as you have said and pointed out in this great series is that it is not much work to switch over to the Cairngorm framework if you do find that the application needs it down the line.
Hi Todd,
Thank you for your comments, and clarification of some of the issues with this approach.
Jon
Comment by Jon — 5 March 2008 @ 08:07I thought this was a good way to introduce the concept of MVC, however I really disagree with the widespread use of singletons.
How do you plan to test your controller when it gets more complex? How are you going to mock the model for testing purposes?
For more information on the appropriate use of singletons please read this article http://www.softwarereality.com/design/singleton.jsp
I also agree with tim that you shouldn’t need to extend from UIComponent, i’d prefer to see a seperate MVC event dispatcher (in which case a singleton is appropriate) used to dispatch and consume these custom events.
Comment by Shanon — 18 March 2008 @ 00:12Hi Shanon,
Thank you for your point of view. Firstly, I understand the concerns regarding singletons. And I agree that in my example, from my articles on extending EasyMVC I have used Singletons for my services which possibly could lead to problems of extendability in the future, however I stand by the fact a singleton should be used to access these services, via a singleton servicelocator (which is the widely agreed approach to locator patterns). This locator creates instances and provides access to the relevant services rather thank accessing them directly. As for the models in the example above, (this uses a modellocator pattern), the ChatModel is a modellocator to the Data Transfer Objects / Value Objects which can actually make testing easier as the test data can be easily injected via the modellocator from within the test rig, and I have used this approach using FlexUnit.
Again I want to clarify that this article puts forward a simple framework that can be used where Cairngorm or PureMVC is overkill. This article was originally presented after Tom Brays Adobe eSeminar was not recorded and has proved to be a very popular approach. It is also designed to allow a fairly trivial upgrade to Cairngorm if needed and my articles on extending EasyMVC are a step towards that.
I also want to clarify that these extending articles are designed to help understand how frameworks like Cairngorm work. I have come accross a lot of developers that are new to Flex come across Cairngorm and implement it without fully understanding it. EasyMVC works well (I use it regularly) where Cairngorm is overkill. Tom could have created a custom eventDispatcher as Caingorm does and then registered event listeners against that but for the sake of simplicity I agree with Tom Bray comments regarding the use of UIComponent.
But like I say the use of design patterns are subjective, their use should depends on the software architects professional judgment, based on the project and project team, not opinions on the web. Although there are always arguments for and against there are no hard and fast rules.
Comment by Jon — 18 March 2008 @ 15:13Hi Jon,
Yes I agree that the service locator and model locator patterns can be VERY useful.
I would like to clarify that theChatModel presented is in fact NOT a singleton. If I never call the getInstance() method I can create as many instances I like:
var chatOne:ChatModel = new ChatModel();
var chatTwo:ChatModel = new ChatModel();
And even if it were a singleton I think using static variables would haven been a lot simpler.
e.g. ChatModel.currentActivity = ChatModel.VIEWING_CHAT;
Now lets say I want to expand on the example and add the ability to join more than one room at once. You simply can’t do it with the chat model as a singelton. Yes you can tell me that you dont need to do this for the purposes of this example, but I’d tell you that anyone who has a need for MVC isn’t developing a one room chat application. And since when was a singleton recommended for the Model in MVC?
Comment by Shanon — 20 March 2008 @ 07:06“Tom could have created a custom eventDispatcher as Caingorm does”
All one would have to do here is extend EventDispatcher, extending UIComponent just to get event dispatching is overkill.
Comment by Tim — 21 March 2008 @ 12:11Sounds like shanon is well versed in singleton theory. The method Jon used to create his singleton is very commonly used in Actionscript.
Even if a private constructor were allowed in Actionsctipt, you’d be able to instantiate two instances of a “singleton” from inside the class itself. If you didn’t use the getInstance() method (as suggested in your comment), then you wouldn’t be abiding by the singleton’s contract to begin with.
Regarding singletons in Actionscript, there has been more of a trend toward using singleton enforcers to compensate for the lack of a private constructor.
Comment by John — 18 April 2008 @ 18:00[...] Le lien http://clockobj.co.uk/2007/10/17/simplified-cairngorm-easy-mvc-for-adobe-flex [...]
Pingback by Comprendre simplement les MVC | Flex actualités — 21 April 2008 @ 11:01As an alternative to the ChangeWatcher to control the view stack, depending on how your application views are structured, you can use binding to easily contorl the view. Bind the view container (which contains the states) currentState attribute to the model’s currentActivity: currentState=”{model.currentActivity}”
Comment by Johan — 25 May 2008 @ 21:19Johan:
I’m a big noob here, but what happens if you wanted to execute something like a state change (or an effect)? Wouldn’t it be easier to watch, catch the event, and then do more than just data bind?
Comment by Chad — 11 June 2008 @ 19:27Hi, Thank you for this good example. I think you have just forget a line for instantiate the instance in your ChatModel class :
If the instance is null you must instantiate like “instance = this” else it’s doesn’t work.
Sorry for my bad English ^^.
Your website is really usefull.
Comment by Skeuds — 9 July 2008 @ 07:50Hi ,
I use a similar approach as explained here
http://techmytongue.blogspot.com/2008/08/mvc-with-flex.html
Thanks,
Venkat
Thanks for this tutorial. I’ve been working with Flex for a few months and I like the end results of a Flex application, but writing well designed code has always been a challenge. This framework looks like something that will make my code a little more robust.
Comment by Austin — 31 October 2008 @ 01:31Lo all,
Great explanations on this site. Been trying out the EasyMVC method, coming from Cairngorm, and I like it a lot. I ran into one problem though and I hope that posting it here will help me fix it.
I let the controller extend UIComponent. Add it and every event I dispatch runs fine. E.g. clicking a button fires a command, no problems there.
Where it goes wrong is when i wanted to fire a e.g. StartApplicationEvent directly after my main view component fires it’s ‘creationComplete’. What happens then is that the systemManager does not receive the event. It just does nothing. The events on the buttons work, because they get dispatched later on.
What I don’t get is, that the controller is initted BEFORE i use the creationComplete to dispatch the AppStart event. putting a trace(systemManager) just before that dispatch does not return null. But still the event doesn’t reach the controller :S.
Any ideas?
Tnx, Ben
Comment by Ben — 25 November 2008 @ 20:00@Jonecir
There is nothing to download with EasyMVC it is simply a process the classes that need to be setup (controller) can easily be cut and pasted from the blog.. That’s about it.
Regards,
Jon
Comment by Jon — 3 December 2008 @ 09:12[...] or Adobe Air applications using MVC design patterns. Claire’s approach to MVC is based on a simplified Cairngorm architecture called Easy MVC and has been optimized to work with the Kerkness PHP framework. It is [...]
Pingback by Claire, A Simple MVC for Adobe Air and Flex - Kerkness.ca — 17 December 2008 @ 00:59Jon,
Still having issues with when the controller is handling events correctly or not. I use the creationComplete or addedToStage events inside the controller to initialize the listeners. Inside my main app I use the creationComplete to dispatch a certain event (which should be handled by the controller). It never reaches the controller it seems? If I use a button’s click handler to fire that same event moments later, it is handled correctly. What am i missing here? It seems the controller is initted too late. But if I add trace statements to the controller and creationComplete of the mainview, it does trace it’s init first and dispatch after…. tracing the systemManager in the init of the controller says it’s NOT null…I’m fresh out of ideas here…
Ben
Comment by Ben — 25 December 2008 @ 11:49