2012-07-22 46 views
0

我正在構建一個Flex應用程序,其中包含檢測變量是否已初始化的問題。觀察這個簡化的代碼示例:Flash實例變量始終爲空?

<fx:Script> 
    <![CDATA[ 
    private var pageObject:* = null; //Yes the "*" data type is needed ;) 

    //Fired by the application elseware 
    private function constructMenu(e:ResultEvent):void { 
     if (this.pageObject != null) { 
     //This block never runs... 

     // The pageObject will be null when the application 
     // first runs, so skip this first time around. 
     // However... this method will be called multiple 
     // times. Since FoodMenu() is a display object 
     // and is instantiated below, all subsequent calls 
     // to this method will require us to remove the old 
     // display object before adding a new one. 
     } else { 
     // This block always runs... 
     } 

     setTimeout(function():void { 
     this.pageObject = new FoodMenu(); //Should now be not-null!!! 

     //Do more stuff with the FoodMenu() and add to the main application 
     }, 1000); 
    } 
    ]]> 
</fx:Script> 

基於給定的代碼示例和意見,可能有人請解釋爲什麼this.pageObject總是註冊爲NOT NULL,無論多少次constructMenu()方法被調用或多少次FoodMenu()的類是實例化的?

謝謝你的時間。

編輯:全MXML的要求

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" 
      xmlns:components="components.*" 
      xmlns:pagesservice="services.pagesservice.*" 
      xmlns:menuservice="services.menuservice.*" 
      minWidth="955" minHeight="600" backgroundColor="0x141414" 
      creationComplete="init(event)" skinClass="skins.Theme" xmlns:pages="components.pages.*" xmlns:reviewsservice="services.reviewsservice.*"> 
<fx:Script> 
    <![CDATA[ 
     import com.asual.swfaddress.*; 
     import com.forwardfour.boncuisson.events.MenuEvent; 
     import com.greensock.TweenMax; 
     import com.greensock.plugins.VisiblePlugin; 

     import components.header.Menu; 
     import components.pages.FoodMenu; 

     import flash.utils.setTimeout; 

     import mx.controls.Alert; 
     import mx.core.IVisualElement; 
     import mx.events.FlexEvent; 
     import mx.rpc.events.FaultEvent; 
     import mx.rpc.events.ResultEvent; 

     import skins.Theme; 

     import spark.components.Group; 

    //Globalize a reference to the navigation menu 
     private var menu:Menu; 

    //Globalize a reference to the page content 
     private var pageObject:* = null; //This reference will be various types, so just make a general object 

    /** 
    * Initialization 
    * ------------------------------- 
    */ 

    //Add an event listener for when "links" on the menu are clicked and initialize SWFAddress 
     private function init(event:FlexEvent):void { 
     //Listen for menu clicks 
      var skin:Theme = Theme(this.skin); 
      this.menu = Menu(skin.menu); 
      this.menu.addEventListener(Menu.MENU_ITEM_CLICKED, menuNavigateToPageHandler); 

     //Initialize SWFAddress 
      SWFAddress.addEventListener(SWFAddressEvent.INIT, initSWFAddress); 
     } 

    //Initialize SWFAddress and grab the page listed from the URL 
     private function initSWFAddress(e:SWFAddressEvent):void { 
     //Listen for change events 
      SWFAddress.addEventListener(SWFAddressEvent.CHANGE, URLNavigateToPageHandler); 

     //Fetch the page from the URL 
      var URL:String = SWFAddress.getValue(); 

      if (URL == "" || URL == "/") { 
       pagesResponder.token = page.getPagesByPosition(1); 
      } else { 
       pagesResponder.token = page.getPagesByURL(URL.substring(1)); 
      } 
     } 

    /** 
    * Navigation handlers 
    * ------------------------------- 
    */ 

    //Go to a specific page when a menu item has been clicked 
     private function menuNavigateToPageHandler(e:MenuEvent):void { 
      SWFAddress.setValue(e.pageURL); 
      pagesResponder.token = page.getPagesByID(e.pageID); 
     } 

    //Request a page when the URL has changed 
     private function URLNavigateToPageHandler(e:SWFAddressEvent):void { 
      var URL:String = SWFAddress.getValue(); 

      if (URL == "" || URL == "/") { 
       pagesResponder.token = page.getPagesByPosition(1); 
      } else { 
       pagesResponder.token = page.getPagesByURL(URL.substring(1)); 
      } 
     } 

    /** 
    * Loading content 
    * ------------------------------- 
    */ 

    //Show an error dialog in the case of an error when communicating with the server 
     private function requestErrorHandler(e:FaultEvent):void { 
      Alert.show("Fault string: " + e.fault.faultString + "\nFault detail: " + e.fault.faultDetail, e.fault.faultCode); 
     } 

    //Determine what kind of page will be constructed 
     private function determinePage(e:ResultEvent):void { 
      var pageType:String = pagesResponder.lastResult.type; 

     //We will need to know the type of page to build 
      switch(pageType) { 
       case "menu" : 
        menuResponder.token = menuFetch.getMenuByType(pagesResponder.lastResult.category); 
        break; 

       case "lunch" : 
        break; 

       case "reviews" : 
        reviewsResponder.token = reviews.getAllReviews(); 
        break; 

       case "home" : 
       default : 
        break; 
      } 
     } 

    //Using the data that was fetched from the "menuFetch" service, construct the page of type menu 
     private function constructMenu(e:ResultEvent):void { 
     //Transition the existing page out of view 
      if (this.pageObject != null) { 
       Alert.show("i"); 
       TweenMax.to(this.pageObject, 0.75, { 
        alpha : 0, 
        y : 20 
       }); 


       removeElement(this.pageObject); 
      } 

      setTimeout(function():void { 
       this.pageObject = new FoodMenu(); 
       this.pageObject.alpha = 0; 
       this.pageObject.y = 20; 
       this.pageObject.data = menuResponder.lastResult; 
       addElement(this.pageObject); 

      //Tween the new menu into place 
       TweenMax.to(this.pageObject, 0.75, { 
        alpha : 1, 
        y : 0 
       }); 
      }, 1000); 
     } 
    ]]> 
</fx:Script> 

<!-- Make a request to the server for the page data --> 
<fx:Declarations> 
    <pagesservice:PagesService id="page"/> 
    <s:CallResponder id="pagesResponder" fault="requestErrorHandler(event)" result="determinePage(event)"/> 

    <menuservice:MenuService id="menuFetch"/> 
    <s:CallResponder id="menuResponder" fault="requestErrorHandler(event)" result="constructMenu(event)"/> 

    <reviewsservice:ReviewsService id="reviews"/> 
    <s:CallResponder id="reviewsResponder" fault="requestErrorHandler(event)" result="constructMenu(event)"/> 
</fx:Declarations> 
</s:Application> 
+0

我們不能告訴你爲什麼總是pageObject註冊爲NOT NULL,除非我們知道如何/時constructMenu被調用。另外setTimeout被調用時。它們如何與頁面的其他元素相關?您將不得不提供完整的組件(MXML文件),以便我們爲您提供更多幫助。 – JeffryHouser 2012-07-22 20:44:13

+0

@ www.Flextras.com已添加相關應用程序的完整MXML。 – 2012-07-22 20:46:48

+0

我在解析代碼時遇到問題,無法確定爲什麼在事件發生時發生。也許你需要提供一個更小,完整的代碼示例來演示問題。 – JeffryHouser 2012-07-22 21:22:03

回答

2

一個可能的問題,我看到是這段代碼:

setTimeout(function():void { 
    this.pageObject = new FoodMenu(); //Should now be not-null!!! 
    //Do more stuff with the FoodMenu() and add to the main application 
}, 1000); 

的「this」指針指的是別的東西(可能是全球對象)在關閉。

嘗試以下操作來查看你的自我:

trace(this); 
setTimeout(function():void { 
    trace(this); 
},1000); 
+2

這正是問題所在......有點驚訝,但我從不使用'setTimeout()'。在匿名函數中(在調用setTimeout()''聲明的)中,this是全局對象,而不是OP期望的類。代碼的行爲與預期相同** IF **您不使用帶'setTimeout()'的匿名/內聯函數,只是將它傳遞給您在類中聲明的函數的引用。 – 2012-07-22 21:16:50

+0

@SunilD。真的很奇怪,但很高興知道!我想這是那個AS與JS不同的那個!讓我試試看。 – 2012-07-22 21:19:08

+0

@SunilD。完全合作!謝謝你們倆! – 2012-07-22 21:30:42