About the ModelLocator in Cairngorm
Cairngorm Design
In Cairngorm, the design proposal is to define the data model into a Singleton object, called the ModelLocator. Cairngorm enforces the use of the Binding mechanism of Flex, in order to automatically update views whenever the model has been modified, such as an object or property change, or even a collection change.
This mechanism is easy to use and quick to develop, however if may eventually grow over time and becomes hard to managed, because of multiple binding events dispatched all over the application. Thus, when the application is big, the ModelLocator may contain dozens of variables, binded here and there throughout the application, and the system will eventually become hard to maintain and understand, if uncontroled bindings are dispatched.
Cairngorm application developers may have spent some time (lots of time?) trying to figure out why this particular view has been unexpectingly updated, to finally point out a binded variable updated somewhere else in the application. Even if you developed the application entirely, you may have troubles with this kind of things.
This is exactly why we designed a watcher for the bindings of the model locator. Moreover, we will also be able to inspect in real time the contents of ModelLocator, as its variables will mostly be bindable.
Usage constraints
- Limitations: at the present time, with version 1.0 of the console, only one ModelLocator is displayed, and if your application has several different ModelLocator instances, you will have to select one of them to be inspected and watched. In a future release, we are likely to overcome this limitation. However, in most cases you will have a single ModelLocator, and this should not be a problem.
- Specify manually the ModelLocator: we are not able to automatically discover what classe(s) of your application implements IModelLocator, or are used as a ModelLocator (after all, ModelLocator is a pure concept with no default implementation provided), so you will have to specify what object to use when instanciating the CairngormConsole. Please, refer to the Integration guide for more details about this.
Inspection of the ModelLocator
The image below displays the contents of the ModelLocator for the demo application:

Once again, this is a regular inspection tree, and works as usual. Remember that you will see only public variables, and that you can send objects to KapInspect through the right click popup menu (KapInspect must have been launched first)
Watch bindings in action !
The binding watcher looks as:

Principles
The BindingWatcher is designed to display the binding events in real time, it will:
- Discover all public variables that are bindable, in all the object composition graph
- Listen to "binding event" on this variables (internally using a Binding object), that can be either a PropertyChangeEvent, or any other event defined as the support for the Binding. Refer to Flex documentation for more information about the Binding metadata instruction.
- Listen to CollectionEvent, for ArrayCollection, in order to trace what happens inside collections (notice that a collection variable does not need to be binded to a List component of the framework in order for this component to update automatically when collection change. Just being a dataProvider for this component is enough, as CollectionChange events are handled by the components)
- Keep an history of all changes on a particular variable, at any level inside the object graph
- Display the stacktrace entry that was the cause of the change in the property
- Inspect data targeted by the changes
Description of the view
- The left pane shows the Bindable public variables found inside the ModelLocator instance provided to the console. If a variable represents an object, then you will able to drill down into this variable definition, and expand the node to see if it contains, in turn, its own bindable public variables. In other terms, the binding watcher listens recursively to change events dispatched at any level of the object graph (tree).
This tree also acts as a filter, for displaying only events that relate to the selected node (and all its subnodes, if any)
- The center pane displays the list of recorded binding events
Description of the columns:
| Column |
Description |
| # |
Number of the event, starting at 1 |
| name |
Name of the property that has been updated, relative to its immediate holder (short name in other terms) |
| chain |
Property name chain within the list of holding objects (ex: myArray.length) |
| value |
The new value of the object, that may be inspected in the object inspector |
| kind |
This is the nature of the event: either PropertyChange, or any other event, or a CollectionChange event |
- The right pane displays an object inspector for the selected object in the main event list, ie the object that is the new content of the watched variable.
- The lower pane displays the stacktrace that is the source of the binding event
Debug bindings
You may now create "watchpoints" on bindings, ie enter debugger when a given binded variable is being modified.
To know more about this feature, please refer to KapInspect documentation
Demo application use case
Startup
- Restart the demo application
- Open the Bindings tab in the ModelLocator tab
- There is one event in the main list, that indicates that the variable named "employeeListDP" has changed.
- Click on the item in the main list, and you will discover that the variable "employeeListDP" is of ArrayCollection type, and that it contains 4 ObjectProxy instances, that are - remember - those retrieved by the LoadEmployees command issued at application startup
- Now, observe the stack trace panel (it is easier with a large screen), you will discover that the collection has been updated in LoadEmployeesCommand.as, line 24, which is inside the result() method, that is called upon service result event:
public function result( rpcEvent : Object ) : void {
model.employeeListDP = rpcEvent.result.employees.employee;
}
Note that you have to bypass the first two entries of the stacktrace, as they refer to the declaration line of the employeeListDP variable, inside AppModelLocator class. This is because when using a variable instead of a setter, the lines that actually trigger the event are "hidden" into the bytecode of the application.
Login
- Now, login into the application, and observe what happens in the watcher view
- The second event concerns the "user" variable, which is set with a new user. Inspecting this object will show the contents of User class: password and username, that are set with the values you just entered. Looking the stacktrace shows that this has been set in LoginEmployeeCommand, line 22 :
model.user = new User( username, password );
- The third event is related to the application state, the value indicating that the application is in view mode
Select an employee
- Now that you are logged in, select an employee in the list
- Event #4 shows that the employeeTemp variable has been updated, with the selected employee, and that this has been done in updateEmployeeCommand, line 22:
model.employeeTemp = new Employee(
selectedItem.emp_id,
selectedItem.firstname,
selectedItem.lastname,
selectedItem.email,
new Date(Date.parse(selectedItem.startdate)) );
- Event #5 shows that the view is now in state 2, through the change of "viewing" variable in the ModelLocator
Delete an employee
- Delete the edited employee and confirm deletion, this will trigger three new changes
- Event #6 indicates that an element has been removed from "employeeListDP", and you can inspect the removed element. This occurred in DeleteEmployeeCommand.as, line 17
- Event #7 shows that "employeeTemp" variable has returned to null state, hence there is nothing to inspect, which occurs in DeleteEmployeeCommand.as, line 22
- Event #8 shows that view is returned to normal viewing state
Conclusions
Using the ModelLocator watcher, we have been able to discover how application data is initialized, and with what values.
Then, we have been able to trace the data flow between different objects of the application, and to pinpoint locations where change occur.
When you have to study or maintain a not-so-well-known Cairngorm application, using these tools could save you a lot of time, and help you in understanding how the application works.
Next >> Commands
|
|