Programming Flex 3: Chapter 20, Embedding Flex Applications in a Browser
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Setting the page title

You already saw how to set the page title for the browser using the init() method. However, the init() method is designed to be called just once, when the application starts. Normally, you'll want to change the page title as the user interacts with the application. You can change the page title at any time using the setTitle() method by simply passing it the title as a parameter.

Handling BrowserManager events

When working with BrowserManager, two events are of interest: applicationUrlChange and browserUrlChange. The applicationUrlChange event occurs when the URL changes programmatically, such as when it is changed via the setFragment() method. Otherwise, when the URL changes because the user clicks the Back or Forward button or because the user changes the URL in the address bar, BrowserManager dispatches the browserUrlChange event. Both events are of type mx.events.BrowserChangeEvent. Typically, you'll handle both events using the same method because most applications should behave identically in all cases regardless of how the URL changes.

Note: The browserUrlChange event does not occur when testing applications locally using Internet Explorer. However, when run from a web server, the event does get dispatched. That means that if you test your application locally using Internet Explorer while developing the application, you will not be able to use the Back and Forward buttons or deep linking features, but it will work when deployed on a web server. Consider testing using another browser, such as Firefox.

Building a Sample BrowserManager Application

In this section, we'll look at a simple example application that uses BrowserManager to enable deep linking and integration with the browser's Back and Forward buttons. The application merely consists of four simple MXML application components corresponding to four screens or pages within the application, and a navigational button bar for navigating between the screens. The four screens are called Home, Books, Authors, and Events.

We'll create these four components first. Three of the four components will consist of nothing more than a label component. One of them will contain an accordion component, and we'll later see how to integrate that into BrowserManager as well. You should define the Home screen component in HomeScreen.mxml using the code shown in Example 20-1.

Example 20-1. HomeScreen.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Label text="Thank you for visiting O'Reilly's Flex site" />
</mx:Canvas>

Next, you can define the Books screen in BooksScreen.mxml, as shown in Example 20-2.

Example 20-2. BooksScreen.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Label text="O'Reilly books catalog" />
</mx:Canvas>

The Authors screen is defined in AuthorsScreen.mxml, as shown in 20-3. This is the screen with the accordion.

Example 20-3. AuthorsScreen.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Accordion id="authorsAccordion" width="400" height="400">
        <mx:VBox label="Joey Lott" />
        <mx:VBox label="Chafic Kazoun" />
    </mx:Accordion>
</mx:Canvas>

The Events screen is defined in EventsScreen.mxml, as shown in 20-4.

Example 20-4. EventsScreen.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Label text="Events this month" />
</mx:Canvas>

This excerpt is from Programming Flex 3. If you want to try your hand at developing rich Internet applications with Adobe's Flex 3, and already have experience with frameworks such as .NET or Java, this is the ideal book to get you started. Programming Flex 3 gives you a solid understanding of Flex 3's core concepts, and valuable insight into how, why, and when to use specific Flex features. Learn to get the most from this amazing and sophisticated technology.

buy button

Now we can assemble all the screens in the main application MXML file with a navigational button bar, as shown in 20-5.

Example 20-5. Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="creationCompleteHandler();" xmlns:local="*" currentState="Home">

    <mx:Script>
        <![CDATA[
            import mx.core.UIComponent;
            import mx.collections.ArrayCollection;
            import mx.managers.IBrowserManager;
            import mx.managers.BrowserManager;
            import mx.events.BrowserChangeEvent;
            import mx.events.ItemClickEvent;

            private var _browserManager:IBrowserManager =
BrowserManager.getInstance();
            private var _navigationData:ArrayCollection;

            private function creationCompleteHandler():void {
                _navigationData = new ArrayCollection();
                _navigationData.addItem({section: "Home",
title: "O'Reilly Publishing", component: "homeScreen"});
                _navigationData.addItem({section: "Books",
title: "O'Reilly Publishing - Our Catalog", component: "booksScreen"});
                _navigationData.addItem({section: "Authors",
title: "O'Reilly Publishing - Meet the Authors", component: "authorsScreen"});
                _navigationData.addItem({section: "Events",
title: "O'Reilly Publishing - Current Events", component: "eventsScreen"});
                navigation.dataProvider = _navigationData;
                _browserManager.init("Home", _navigationData.getItemAt(0).title);
            }

            private function itemClickHandler(event:ItemClickEvent):void {
            }

        ]]>
    </mx:Script>

    <mx:VBox>
        <mx:ToggleButtonBar id="navigation" labelField="section"
itemClick="itemClickHandler(event);" />
        <mx:Canvas id="sections" />
    </mx:VBox>

    <mx:states>
        <mx:State name="Home">
            <mx:AddChild relativeTo="{sections}">
                <local:HomeScreen id="homeScreen" />
            </mx:AddChild>
        </mx:State>
        <mx:State name="Books">
            <mx:AddChild relativeTo="{sections}">
                <local:BooksScreen id="booksScreen" />
            </mx:AddChild>
        </mx:State>
        <mx:State name="Authors">
            <mx:AddChild relativeTo="{sections}">
                <local:AuthorsScreen id="authorsScreen" />
            </mx:AddChild>
        </mx:State>
        <mx:State name="Events">
            <mx:AddChild relativeTo="{sections}">
                <local:EventsScreen id="eventsScreen" />
            </mx:AddChild>
        </mx:State>
    </mx:states>

</mx:Application>

In this code, we define an ArrayCollection called _navigationData, and we add four elements to it. Each element corresponds to a screen in the application. Each element has three properties: section, title, and component. The section corresponds to the name of the state for the screen, the title is the page title, and the component is the ID of the screen component instance. Then we assign the _navigationData collection to the dataProvider property of the ToggleButtonBar instance. This will create four buttons corresponding to the four screens.

At this point, nothing happens when you click the buttons because we haven't defined the behavior. Typically, if you wanted to change the state when the user clicked on a button, you would simply set the currentState property. However, in this case we want to route all requests for state changes through BrowserManager. That means we need to call setFragment() instead. And that means the new, revised method now looks like the following:

private function itemClickHandler(event:ItemClickEvent):void {
    _browserManager.setFragment(event.item.section);
}

This code sets the fragment to the value of the section property of the dataProvider element corresponding to the button. The result is that the fragment will be one of the following: Home, Books, Authors, or Events, which just happen to also correspond to the names of the states.

If you were to test the application at this point, you'd see that the fragment does indeed update when you click the buttons, but the application state doesn't change. To change the application state we need to handle the applicationUrlChange event. We can do that by first registering a listener for the event in the creationCompleteHandler() method with the following code:

_browserManager.addEventListener(BrowserChangeEvent.APPLICATION_URL_CHANGE,
urlChangeHandler);

Then we need only to define the urlChangeHandler() method. This new method looks like the following:

private function urlChangeHandler(event:BrowserChangeEvent):void {
    var fragment:String = _browserManager.fragment;
    var item:Object;
    for(var i:int = 0; i < _navigationData.length; i++) {
        if(_navigationData.getItemAt(i).section == fragment) {
            item  = _navigationData.getItemAt(i);
            navigation.selectedIndex = i;
        }
    }
    _browserManager.setTitle(item.title);
    currentState = item.section;
}

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Next Pagearrow