Learning Flex Part 4: Cairngorm Events != Flex Events

One thing I struggled with while learning about Cairngorm is the Cairngorm Event model. In short, Cairngorm Events are quite different from standard Flex Events in the way they are handled.

This may be obvious to seasoned users of Cairngorm, but this took me a while to wrap my head around. Cairngorm Events map to Commands via a Cairngorm Controller. They are (as I understand them) meant to update the ModelLocator and get data from the server (via Delegates and Responders). They don't "bubble" up the Flex container hierarchy, and they don't get announced to the rest of the Flex application.

My first instinct was to try and decouple my Views from Cairngorm by having them only announce Flex events. These events would bubble up the container hierarchy and be handled at the top level of the application. From there, corresponding Cairngorm Events would be dispatched. This way, I could still have non-Cairngrom event listeners respond to the bubbling events, and my Views would be decoupled from the Cairngorm framework, which sounded like a good idea.

However, with more experimentation and thought, I've realized this approach adds complexity and doesn't offer much in the way of benefits. It requires a separate layer of event mappings so that the Flex events can be translated into Cairngorm events. And in most cases, your Views are tied to Cairngorm anyway. For example, a Shopping Cart panel is directly tied to the ModelLocator to keep track of what is in the cart. You can't easily reuse this Cart component in a non-Cairngorm app without changing it. The same thing probably applies to most of the Views. So in retrospect, in most cases I believe it is fine for your Views to just go ahead and dispatch Cairngorm events and avoid all the overhead of trying to make them framework independent.

Now, I can see that for certain kinds of components, this would not apply. If you truly have a reusable component, say a custom Select Box for picking States or something, this would benefit from being totally decoupled from Cairngorm. You can have it dispatch a custom Flex event that the parent container would then handle by dispatching a Cairngorm Event. So it appears that one must consider the purpose of the View component in question and decide whether it is application-specific or application-independent. The answer would seem to dictate whether it is appropriate to announce Cairngrom Events vs. Flex Events.

I'm interested to hear from anyone more deeply familiar with Flex and Cairngorm. Is my thinking on the right track on this? Please fire away in the comments and let me know your thoughts. Thanks!

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
I agree with you that there are UI-components that are reusable in different applications with of course should not be related to Cairngorm in any way.
What I find hard to decide is where (low/high level components) to start using application-specific components.
IMO it would be better if only high-level-components would have dependecies to Cairngorm i.e.: giving some model to all its sub-components and getting events from it's children and dispatching them to the front controller.
But then again ... that's often wasted effort.
# Posted By Norbert Kopcsek | 1/4/08 12:39 PM
Cairngorm as well as most of the other Flex frameworks (except for Sim's easyMVC) takes the approach of creating their own global event system seperate from the one Flex provides. Unless you create helper classes for each view which act as delegates to make your call to dispatch Cairngorm events, usually any custom handlers you write in the view need to be refactored when moving between the frameworks.

I think exploring Cairngorm was a very important step in learning to work with Flex for me, but I definitely think it's worth re-evaluating the tools that Flex already provides. Flex's event system is pretty powerful based on the parent/child relationship components assume when configured via MXML. Additionally, using custom non-visual components can supplement and simplify almost anything most Flex frameworks due via Command or Proxy objects. I wrote a post about using these components (http://www.brianlegros.com/blog/2007/12/13/uses-fo...) and Max Porges has a great talk coming up at cf.objective about using Flex without frameworks.

Just some things to consider. Best of luck on your journey!
# Posted By Brian LeGros | 1/4/08 12:49 PM
I'm interested to hear what Max has to say since he is such a sharp guy. However, based on the general idea that he's putting forward, I'm not convinced. I'm sure that it is completely possible to build a robust Flex app without a framework like Cairngorm, but to do so puts the onus on the developer to handle things the right way and put things in the right place. Cairngorm, for better or for worse, forces a certain set of conventions on you, such as Controllers, Commands, Delegates, etc. I'm sure very skilled people like Max have no problem implementing these in their own way, but for most people I still think a common framework helps force good practices and separation of concerns upon you.

To compare it to ColdFusion, I know it is completely possible to avoid using something like Model-Glue, but doing so means that you have to implement most of the ideas yourself since the framework is set up the way it is for a reason: forcing you to drink the "good practice kool-aid".

There's also the argument for teams, where it would be difficult to argue that using a known and widely understood framework makes things easier since everyone knows where things are and what each piece does. When you have your own framework, there is usually extra work involved in simply figuring out what is going on or creating your own guidelines that must be adhered to.

All the same, I'll be keeping my ears open for what he has to say!
# Posted By Brian Kotek | 1/4/08 1:00 PM
Brian, we use a mixture of Flex Events and Cairngorm Events on our projects. Our Cairngorm Event/Command/Delegate sequences are used specifically for changes to our Model (which then may trigger a lot of different View changes depending on binding). We use Flex Events whenever a user action does not require the Model to change (although often the handlers for these Events trigger Cairngorm Events, too).
# Posted By Leif Wells | 1/4/08 1:12 PM
@Brian - I definitely understand the framework argument from the perspectives you're pointing out. I do think however that you've got a market of developers coming from the stateless HTTP world who are starting to use Flex and introduce solutions like frameworks as ways to be organized and it's simply overkill. If you look at Swing or Windows Forms or other GUI toolkits you see frameworks being used as an edge case, not the norm. Flex makes so many things in this rich UI domain easier, that frameworks seem to provide more boiler plate code than its worth for the potential in organization they may provide. I think modeling is much better way to keep organized and simplify your code base.

That being said, I learned a lot from going the framework route, so I can definitely understand and appreciate your perspective.
# Posted By Brian LeGros | 1/4/08 3:07 PM
Hey Brian, I can really appreciate this post, as I have only recently learned Cairngorm myself as I was starting a new project. Your post intrigued me because you are coming across the same thoughts and musings as I am. With that I would like to share with you my current convention.

You are extremely close, in my opinion, to finding the correct way to determine what part of the application should announce Flex events and which one should announce Cairngorm events. For me, basically my main layout containers are the ones that have visibility to reading from the model and dispatching Cairngorm events. This is usually only as far down as the 2nd level from the top. Everything else below that, I ensure that any custom component is reusable.

In my case right now, I am building a dashboard for a customer that will allow them to input various transactions as well as edit, delete etc. They will also be able to run various different types of queries and reports on these transactions.

The dashboard at it's highest level is basically a tab navigator. The second level, is the container that holds the contents for each tab. Everything inside that container still reads the modelLocator and still announces the Cairngorm events. However, components below that are all reusable (even if they are custom) and internally announce only Flex events.

By setting this restriction in the beginning for myself, I have been forced, or rather encouraged, to ensure that my custom components are reusable. I have yet to come across a problem where they may not be. Keep in mind, that reusable doesn't necessarily have to be reusable outside that project. If a particular component is using a very specific arrayCollection of ValueObjects that are defined in relation to this application, it may not be reusable outside the the context of this application, but it can still be reused somewhere else in the application. Therefore, you have saved yourself that much recoding within the project itself.

Another thought that I wanted to make that I have not set in stone as a personal process for me, is the way I set up my Cairngorm event structure. It seems that the defined structure is supposed to be a single event class, with a single event defined in it, to map to a single command. To me, this seemed like overkill in my events folder. What I have done in this project, is a I create an Event class that represents a category of events. Let's say our application dealt with the management of customers. The Event class would be called CustomerEvent, and would define types of events internally as ADD_CUSTOMER, EDIT_CUSTOMER, DELETE_CUSTOMER etc etc etc.

I am curious to hear your thoughts. Thanks. Btw, your post may inspire me to write about my own journey with Flex/Actionscript + Cairngorm on my blog as well.

Thanks!
# Posted By Kyle Hayes | 1/7/08 12:22 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1. Contact Blog Owner