Recap: In Part 1, I discussed the basic implementation and use of the ModelLocator pattern. This pattern is one of many design patterns contained within the Cairngorm micro-architechture. This design pattern will be used in Part 2 as well, so it is assumed that you are familiar with the concepts in Part 1 of the tutorial. At this point, we still are not working with a "complete" Cairngorm application (that will come in Part 3).
Part 2 - Using a ModelLocator to Manage the View
Note: As with all of the tutorials that will come in this series, this lesson has two parts. First, in the article you will learn the theory behind the topic, and then in the video you will do an actual "code-along". The article will give some instructions in how to set up your project for the "code-along".
In the previous tutorial you learned the advantages of using a ModelLocator to manage data within an application, however, the advantage of the ModelLocator pattern extends beyond the management of data. It can manage the "view" of an application as well. To see how view management works in Cairngorm, you will first need to create a new project named "ViewManager" and name the main application file "Main.mxml". For this project, your will also need to add the Cairngorm.swc to your project build path (as described in Part 1). You will also need to create two new folders inside of the "src" folder: view and model. When you are completed, your project should look similar to Figure 1 below.

Figure 1 - ViewManager Project
Next, you will need to take the ModelLocator code from the previous tutorial and place it inside your application. I have posted the code below for your convenience.
Example 1 - The ModelLocator from Part 1
If you need information about the ModelLocator, please return to Part 1 of the tutorial.
The only item that must be changed in the ModelLocator is the "package" statement. For this project, you will be placing the ModelLocator in the "model" folder, so the package path simply needs to me "model" (it has already been corrected above). You will also need to add one variable to your ModelLocator initially. This variable will be called "workflowState" and it will be of type "uint". The declaration will look like this:
Example 2 - Defining the workflowState Variable
This variable will be used to "control" the view in your application. The most common way to accomplish this is to use a ViewStack [ Reference ]. If you are not familiar with a ViewStack, feel free to read through this information. A ViewStack has a property named "selectedIndex". This numeric value defines which "child" is visible in the ViewStack. Consider the following code:
Example 3 - A Basic ViewStack Example
Initially the value of selectedIndex is 0. With this setting "box1" would be visible. If you issue the following command:
Example 4 - Manually Setting the selectedIndex
then the box named "box2" would be visible. However, if you apply the ModelLocator to this concept, you could use the workflowState varaible to set the selectedIndex property. By binding the selectedIndex to the workflowState value, you now have complete control over what is displayed in the ViewStack from your ModelLocator.
Example 5 - Binding the selectedIndex to the workflowState
Defining Constants for Better Code
It would be simple to manipulate the view using this method, however, it could lead to potentially confusing code. For example, assume that you have the following:
This might seem as if it works properly, but it doesn't account for any changes. If another child is added to the ViewStack, it could throw off the order. There needs to be a better way to manually set the selectedIndex property. To accomplish this you just need to define constants inside of the ModelLocator.
Example 6 - Defining View Constants in the ModelLocator
By using this method, you only have to change the value in one location if the number of children or the order of the children changes in the ViewStack. Now, you would assign the login button the following action to the click event:
Example 7 - Setting the View with Defined Constants
Not only do you protect against future changes, you also have made your code much more logical. Another developer could easily look at the code and understand the process without having to reference all of the children in the ViewStack.
NOTE: The audio was not that great for this video. I will be using a better system for the next tutorial.
Video Example - Controlling the View with a ModelLocator
Application Code
Download (3 kB)
These tutorials are very helpful coming from a person who has a somewhat limited programming background. I have done a lot of searching online and find your material to be the most easily understood thus far… can’t wait for part 3.
Hi from Finland!
Thanks for creating these tutorials! helps me alot! Keep up good work! Whats gonna be in next part?
I am working on Part 3 right now. Part 3 is the Introduction to the full Cairngorm Micro-Architecture. It will cover the Cairngorm Event Flow and the organization of a Cairngorm project.
[...] Teil 2 dreht sich um die Implementierung des Views mittels des ModelLocator Patterns [...]
Hi David,
May I download your flv file.the movie is very useful for me.Thanks
[...] Part 2 [...]
[...] Part 2 [...]
[...] http://www.davidtucker.net/2007/10/18/cairngorm-part-2/ [...]
[...] Tradução do original inglês: http://www.davidtucker.net [...]
Hi,I’m from China.
These tutorials are greet && thanks you!
Hi,
I’m from South Africa and I have been battling with the framework until I stumbled on this tutorials. Thanks to you i now have my view managers setup. Now I’m off to Part 3!! You are great teacher & trainer.
Great stuff. Thanks for taking the time to publish it.
[...] Getting Started with Cairngorm – Part 2 [...]
[...] Tucker :: Getting Started With Cairngorm :: Part 1 :: Part 2 :: Part 3 :: Part 4 :: Part [...]
My homepage.
[...] Getting Started with Cairngorm – Part2 [...]
Recently, following your generous tutorials, David, and in an attempt to get the very basic flex-cairngorm skills (by building a helloWorld app, naturally) i bumped into an issue – “unable to bind to property XXX on class ‘Object’ (class is not an IEventDispatcher)”.
After googling for a while, giving up, googling again, although it seemed that i’m not the only one having the problem, i couldn’t find anything ‘comprehensible’.
The forms of this warning can be various probably – in my narrow case, it’s a datagrid, that isn’t populated. In others – it’s a view, not responding to changes of a model, but sending a warning to the console.
I haven’t yet delved into the nature of the problem – being a novice it’s already tough the way it is; so far, this is what i was able to make out.
The case.
The application is meant to fetch entries from a db table using 2 different ‘gateways’ (AMFPHP and ZendAMF). Beside this, i thought it wouldn’t be a bad idea to check on the time it takes for each gateway to do it. So, beside a returned recordset it would be nice to have timestamps.
The model:
[Bindable]
public var amfphp:Object = new Object();
//recordset via AMFPHP (fed to datagrid 1)
[Bindable]
public var zendamf:Object = new Object();
//same recordset via ZendAMF (fed to datagrid 2)
When handling the result, if you do this:
model.amfphp = data.result
//set amfphp to the recordset, Array
“{model.amfphp}” it works fine
If you do this, however:
model.zendamf.dg = data.result
you get the warning, and the datagrid isn’t populated.
The reason you want to do “model.zendamf.dg” is because you want to add some extra properties, like:
model.zendamf['reqTime'] = xxxx;
model.zendamf['curTime'] = xxxx;
So, you ask yourself something like – models can’t or shouldn’t be ‘nested’? What/where is the misunderstanding or misuse?
@goliath – The issue here is that an Object can’t dispatch an event (which is required for binding). You aren’t meant to bind variables to an object’s property. A quick alternative might be to use ObjectProxy. Your other option might be to not utilize an object and bind it to a strongly typed variable.
Thanks for the prompt reply, David
i’ve been digging for quite some time, but with little luck so far.
>>The issue here is that an Object can’t dispatch an event (which is required for binding)
Yes, i think i got that. The Adobe manuals has the details on binding to Objects or their properties. But there is something confusing here (i might actually be missing out on those ‘details’):
model.zendamf.dg
- dg IS a property of an Object
- but the value associated with it – is an ArrayCollection
“{model.zendamf.dg}” seems like a binding to the ArrayCollection; not to a an object’s property
the events dispatched by the ArrayCollection are the ones that the binding should listen for, no? Not the events dispatched zendamf by the object zendamf?
So, the idea was to have ‘amfphp’ and ‘zendamf’ as a way of grouping data, that is a result of calling the 2 gateways and not having something like:
var amfphp_dg
var amfphp_curTimestamp
var amfphp_reqTimestamp
i.e. moving the datagrid just a bit lower in the hierarchy to keep everything more ‘tangled’.
There must be a better way than defining all these variables beforehand, so as to have them ‘bindable’?
i will take a deeper look into the ObjectProxy
Thanks again for the answer/guide/tips
Hello,
Thanks for setting up a bunch of very useful tutorials!
I just wonder, if there are multiple nested view stacks within an application, what’s the best way to handle those?
For instance, the main app has a view stack VS1, which uses a custom MXML component containing VS2.
So the trick here is that the state change events should modify current state of VS2, not VS1.
So what’s the best way to handle it? Create multiple ViewModelLocators, one for each view stack?
Thanks.
Nick.
Ur blog is awesome …u made my life easy …thank you ..keep up the great work ..ur a gifted trainer …
nice job!
I read in the cairngorm documentation that the ModelLocator should not be use to stock variables but just their definition. There were no example after this affirmation.
My interpretation of this sentence is that in the ModelLocator you can do that:
public const imagePath:String;
but not that:
public const imagePath:String=”../products/”;
I wonder if declaring constant in the ModelLocator is a good practice.
[...] 2)Part-2 [...]
[...] Artigo sobre Cairngorm parte 2 e o Vídeo Cairngorm Part 2 [...]
Hi. I needed to drop you a quick note to impart my thanks. I’ve been watching your blog for a month or so and have picked up a heap of sound information as well as enjoyed the way you’ve structured your site. I am setting about to run my own blog however I think its too general and I would like to focus more on smaller topics.
[...] Getting Started with Cairngorm – Part2 [...]
Excelente turorial David…
Gracias por tomarte la molestia de enseñar a otros…
hi David,
I can, without even a single instance of doubt, term your tutorial as the most simple and the best tutorial, for beginners in flex applications implementing MVC. now I am heading towards part 3. Please keep on your good work.