4 Replies Latest reply on Nov 29, 2010 5:19 PM by WordRad

    Deep Linking problem

    olegkon Level 1

      Hi,

       

      I am trying to add Deep Linking to the large Flex3 app

      (it has one main HTML file and collection of dashboards selects one via ComboBox).

      so I would like to be able to send a link like  http://myserver/myapp.html#/dashboard1

       

      New to SWFAddress, so please bare with me.

       

      I have seen a Flex sample coming with SWFAddress:   http://www.asual.com/swfaddress/  (click Flex link)

      and tried to integrate it into my app.

       

      So far I was able to put that  fragment id (#/dashboard1) when this particular dashboard (db1) is selected.

      But if I go to Firefox and change it to say, #/dashboard2, nothing happens, it never goes to call  

      handleSWFAddress() change event handler.

       

      I do have JS libraries in place, declared in HTML,

      and SWFAddress.swc in lib of that FB project.

      Haven't changed Helper.as much from original sample.

       

      So here is a skeleton of my app:

       

      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
          name="Dashboard" ...  
          applicationComplete="initSWFAddress()"
          currentStateChange="setSWFAddress()" >

       

      <mx:Script>
              <![CDATA[

       

                private function selectDashboard(name:String):Dashboard {
                      var dashboard:Dashboard = Dashboard(this.contentStack.getChildByName(name));
                      //dashboard=null;
                      if ( dashboard == null){
                          dashboard = this.createDahsboard(name);
                          if (dashboard != null) {
                              this.contentStack.addChild(dashboard);
                          }
                      }
                      this.selectedDashboardIndex = this.contentStack.getChildIndex(dashboard);
                      var ctlTool:DisplayObject = dashboard.getToolbarControl();
                      //Remove old toolbox
                      var oldTool:DisplayObject = this.appControlBar.getChildByName(TOOLBOX_NAME);
                      if (oldTool != null) {
                          this.appControlBar.removeChild(oldTool);
                      }
                      //Add toolbox if any
                      if (ctlTool != null) {
                          ctlTool.name = TOOLBOX_NAME;
                          this.appControlBar.addChildAt(ctlTool,3);
                      }

       

                      // change Fragment
                      SWFAddress.setValue("/"+name);
                      Alert.show ("set dashboard: "+name);
                     
                      return dashboard;
                  }

       

                 private function onChangeDashboard(e:Event):void {               
                      var currDashboard:Dashboard = Dashboard(this.contentStack.selectedChild);
                      currDashboard.beforeCloseDashboard();
                      this.contentStack.removeChild(this.contentStack.selectedChild);
                      var name:String = ComboBox(e.target).selectedItem.toString();
                      GlobalComponents.instance.resetSession();
                      this.selectDashboard(name);
                  }

       

       

                  private function initSWFAddress():void {

                      handleSWFAddress(new SWFAddressEvent(SWFAddressEvent.CHANGE));

                      SWFAddress.addEventListener(SWFAddressEvent.CHANGE, handleSWFAddress);

                  }

       

                  private function setSWFAddress():void {
                      Alert.show("in setSWFAddress()");
                      Helper.setSWFAddress(this);
                  }
                 
                  private function handleSWFAddress(event:SWFAddressEvent):void {    // never gets called  !

                      // switch to new Dashboard
                      var name:String = SWFAddress.getValue();
                      Alert.show("handleSWFAddress()  DashboardIndex: "+selectedDashboardIndex+", setting Dashboard to fragment id (Name): "+name);
                      this.selectDashboard(name);

       

                      Helper.handleSWFAddress(this, event);
                  }
              ]]>
          </mx:Script>

       

              <mx:ComboBox  id="dashboardChooser" toolTip="Click to select a Dashboard"
                                   tabIndex="0" dataProvider="{this.dashBoardList}"
                                   change="onChangeDashboard(event)"/>              
         
              <mx:ViewStack id="contentStack" width="100%" height="100%" selectedIndex="{this.selectedDashboardIndex}" styleName="blue2BG">       
              </mx:ViewStack>

      </mx:Application>

       

      Few caveats:

      1) we do use States in that MXML file for something comletely irrelevant.  Was hoping to use it with ComboBox.  Is States necessary for SWFAddress?

      2) we do use history.js for browser history, but not deep linking (hope it doesn't interfere with SWFAddress)

      3) I did not put SWFObject.js - not in that sample

      4) I did not put Google Analytics JS - hope it is not required for SWFAddress (Event) to work.

       

       

      Please help !

       

       

      TIA,

      Oleg.

        • 1. Re: Deep Linking problem
          Flex harUI Adobe Employee

          You may need an update to the history.js.  Corey Lucier posted updates

          within the last few months.

          • 2. Re: Deep Linking problem
            WordRad Level 1

            The startup sequence I have is the following:

             

             

            <?xml version="1.0" encoding="UTF-8"?>
            <mx:Application
            ...

              initialize="{InitWRX()}"
            >

               
                private function InitWRX() {
            ...   

                    SWFAddress.addEventListener(SWFAddressEvent.EXTERNAL_CHANGE, InitWR0, false,0,true);           
                
                 
                }

             

                private function InitWR0(event:Event = null) {
               ...                        
                    crnt_path = SWFAddress.getValue().substr(1);           
            ...           
                  ChildWR(crnt_path,bRel);
                   
                }

             

             

            SO iow, I'm thinking you should only call addEventListener(SWFAddressEvent.EXTERNAL_CHANGE...) in your function initSWFAddress.  (Furthermore, I only listen for EXTERNAL_CHANGE, not CHANGE.)

             

            You say HandleSWFAddress never gets called, but I'm thinking it gets called, but that SWFAddress.getValue is not working in it, because you need to addEventListener(SWFAddressEvent.EXTERNAL_CHANGE..)  first in initSWFAddress and then don't call HandleSWFAddress manually, but let the eventhandler call it.

            • 3. Re: Deep Linking problem
              Lee Burrows Level 4

              apologies if i misunderstand you, but you do need SWFobject otherwise SWFaddress doesnt work (when you change the browser url).

               

              also the <script> tag for SWFobject js needs to be before the <script> tag for SWFaddress js in your html

              • 4. Re: Deep Linking problem
                WordRad Level 1

                FYI - You do not need SWFObject for SWFAddress to work.

                You do need the correct swfaddress  .js files included in the html

                 

                SWFAddress complicates things by not providing adequate documentation for some unknown reason.

                 

                I do think his problem was as I outlined in my post above - He should call AddEventListener(SWFAddress.EXTERNALCHANGE...) first before attempting SWFAddress.getValue, and actually have the event listener for EXTERNAL_CHANGE be the sole trigger for that HandleSWFAddress fuinction he wrote, which he says never gets called but it  is- its just that getValue call in it isn't working.

                 

                At any rate SWFObject is not mandatory.

                 

                edit:

                He does need to run the Flex htrml template that calls AC_FL_RunContent (from ac_oetags.js)  but that is one of the standard FLex html templates.  Maybe SWFObject handles this automatically, but its not mandatory.