Deep linking within a flash application has been a topic of much discussion. In 2006, Alan Shaw gave a presentation to Flash Coders NY about AS2 deep linking techniques. At the time, it seemed far too complex for the effort. Fortunately with Flex 3, Adobe introduced (drumroll) The BrowserManager. It's not perfect yet, but it works pretty well.
Working example: http://www.9mmedia.com/examples/deeplinking/
Get the code: http://svn.9mmedia.com/public/deeplinking/
Deep linking provides a number of useful opportunities to a web application. Most importantly it opens access to your application through reading your browser's url. For example, to get to the "Process" page on the 9mmedia website, you can go direct with this link: http://9mmedia.com/#section=how;subsection=process This benefits users for bookmarking and google, creating links directly to a section or "state" of your application.
The BrowserChangeEvent.BROWSER_URL_CHANGE event is fired by the BrowserManager which is listening for a call from javascript when the URL changes. The javascript functions are located inside your history.js which lives in your automatically generated, html-template directory.
Here is a snippet demonstrating instantiation of the BrowserManager. It's extremely important to remember to call browserManager.init(); (Trust me, the browserManager won't work otherwise.)
View CodeACTIONSCRIPT | |
private function onCreationComplete(event:FlexEvent):void{ //create new instance of BrowserManager singleton. browserManager = BrowserManager.getInstance(); browserManager.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE, onBrowserUrlChange); //super important to call init. won't work otherwise. browserManager.init(); } | |
Part 1. Deconstructing Fragments
The BrowserChangeEvent will have a property, event.fragment, that contains a string of everything in the url after the "#", ie. "id=section1". In this example, the name-value pairs within the fragment will correspond to the children inside the ToggleView component.
View CodeACTIONSCRIPT | |
/** * handles event when the url has changed in the browser. * **/ private function onBrowserUrlChange(event:BrowserChangeEvent):void{ if(browserManager.fragment && browserManager.fragment!="" ){ gotoFragment(browserManager.fragment); } } /** * converts the string after the # sign in the browser to an object * **/ private function gotoFragment(fragment:String):void{ parsing = true; //flag used in navigate function //finds the matching section object in our dataProvider var fragmentObj:Object = URLUtil.stringToObject(fragment); var section:Object = getSectionById(fragmentObj.id); navigate(section); parsing = false; } | |
My ToggleView.mxml has a container of sections(VBoxes). The name of each VBox inside the ViewStack corresponds to the value of the id in the fragment. Look at the code to see the setup.
Part 2. Constructing Fragments
The BrowserManager also handles setting the url. This is done by passing in the name-value pair to the setFragment function.
View CodeACTIONSCRIPT | |
/** * This function is the only way to navigate, used for * handling url links as well as user interaction with our menu. * * Requires an object with an id and name property, matching * an entry in the dataProvider. * **/ private function navigate(section:Object):void{ //This actual does the navigation, changing the visible section toggleView.setSelectedSection(section); if(!parsing){ //* insures browser isn't changing and being changed at the same time. browserManager.setFragment("id="+section.id); //changes url browserManager.setTitle("9mmedia - "+section.name); //changes title of browser. } } | |
Overall Deep Linking is a feature that's long overdue. It's a feature that's easy to use, and a powerful tool in creating accessible flash websites.
download the code: http://svn.9mmedia.com/public/deeplinking/
I feel the need to preface that my code follows a fairly basic design pattern. It uses the Code Behind technique so that .mxml classes have corresponding base.as classes.
Click here to view the working example.
Known Deep Linking issues:
Doesn't support Opera browser yet.
Issues I've encountered so far:
- Hard to debug when BrowserEvent.URLChange, because refreshing the browser disconnects the debugger.
- Don't forget to init()
- Used Alert windows to trace() if need be.
- Adobe has modified code between beta 2 and beta 3. Hopefully won't occur again.
resources:
flexwiki.adobe.com
If you want to use BrowserManager with SWFAddress instead of Adobe’s embed code have a look here:
http://blog.iconara.net/2007/12/28/deep-linking-in-flex-using-swfaddress-and-browsermanager/