Learning Flex – Lesson 15, Implementing History Management

Using history management, a user can navigate through an application using the browsers back and forward operations as they would at a regular website.

Flex automatically supports this behavior for any navigation container. The property used to specify this is the boolean historyManagementEnabled. It’s true by default for Accordion and TabNavigator but false for ViewStack.

It works by saving the state of navigation as the user moves within the app (note only the container state is saved, not that of any components within it) and when the browsers back or forward buttons are selected, the HistoryManager loads the relevant state.

History management uses an invisible HTML frame into the browser window. The state of the container is encoded into the URL parameters for this frame. A javascript called history.js located in this frame decodes the parameters and sends the relevant information to the HistoryManager class in Flex.

By default, Flex Builder will create a HTML template for a swf with history management capabilities, Flash Develop will not. You can manually edit the created HTML file using the templates found under your SDK \templates\html-templates directory. If you want to change this default behavior, copy one of the templates from your SDK to your Flash Develop \projects\140 ActionScript 3 - Flex 3 Project\bin directory.

Note that history management will not work in IE when running a Flex app from a local file due to security constraints. It will work once deployed to a server and Firefox will show the correct behavior in both cases.

History management can be added to any custom component by following the steps below:

  • specify the custom component implements IHistoryManagerClient
  • implement loadState(), saveState() and toString() to satisfy the interface
  • call the static methods of the HistoryManager class to register() the custom component and save() when the navigation state changes.

To specify a class implements an interface in ActionScript, you would add implements interface (where interface is the interface class name) to the end of your custom class name definition eg public class MyClass implements IHistoryManagerClient. In MXML, you add an implements attribute to the end of your container tag eg <mx:HorizontalList ... implements="IHistoryManagerClient">

On creation complete, you should use HistoryManager.register(this) to register the component. At this point you must also call HistoryManager.save() to initialize the state.

If the component is a subclass of UIComponent, it will already have a toString() method. The saveState() method should return an Object that contains name,value pairs that represent the navigation state. As the URL size is limited, this data should be kept to a minimum. You would normally save something like the selected index for the container.

The loadState(state:Object) method is activated when the user clicks the forward or back buttons on the browser. The history manager passes in the Object created by the saveState() method for the container to use in deciding what navigation state to display. This object should be checked for null in case the user clicks the back button when there is no history to go back to.

HistoryManager.Save() should be called any time the component changes it’s navigation state so the history manager can keep track of what state the component is in.