2012-01-26 52 views
0

我正在爲網站構建應用程序,該網站將通過攜帶某些產品/品牌的商店進行過濾,並將結果顯示在List組件中。我一路裝載數據,將品牌/國家/城市置於組合框中,以便用戶可以過濾他想要查看的國家和城市以及哪個品牌。直到現在沒有問題。我的問題是,雖然數據提供者在將某些值硬編碼到我用於每個條目的項目渲染器的標籤時應該如此工作,但我無法從數據提供者獲取真實數據..您將在下面的代碼中看到,在VGroup組件(我用於列表中的每個商店)中有4個標籤,其中3個是硬編碼的,只是爲了查看它的工作原理。其中一個標籤雖然試圖從xml文件中獲取真正的數據,那就是我停止的地方。在我見過的所有教程(以及文檔)中,每個人都會點擊「data.XYZ」,其中XYZ是要獲取的屬性或節點的名稱。在我的情況下做同樣的事情只會返回一個錯誤「1120:訪問未定義的屬性數據」。我究竟做錯了什麼?我已經花費了幾個小時來迭代數百個flex的例子,無論是新舊版本,我都無法找到該做什麼。當所有其他人都進入這個最後的小事情時,它真的很傷腦筋!看看代碼,讓我知道如果我做錯了什麼或錯過了什麼!發佈下面的代碼。也有一個XML文件,但它正確加載和不同的xmlLists DO有正確的節點存儲,所以我不認爲它需要張貼,除非你認爲另有規定。每個商店的XML節點是「標題」,「電話」,「郵件」,「城市」,我堅持試圖獲得標題。最重要的函數是filterShops,然後是整個列表和itemrenderer塊。在flex應用程序中無法從數據提供者獲取數據

<?xml version="1.0" encoding="utf-8"?> 
<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" 
       width="815" height="578" minWidth="955" minHeight="600" 
       creationComplete="sendData()"> 

    <fx:Style source="styles.css"/> 

    <fx:Declarations> 
     <s:HTTPService id="shopsService" url="data/places.xml"  result="shopsService_return(event)" resultFormat="e4x"/> 
    </fx:Declarations> 

    <fx:Script> 
     <![CDATA[ 
      import mx.collections.ArrayCollection; 
      import mx.collections.XMLListCollection; 
      import mx.events.FlexEvent; 
      import mx.rpc.events.ResultEvent; 

      import spark.events.IndexChangeEvent; 

      private var placesXML:XMLList; 

      [Bindable] private var countriesList:XMLListCollection; 
      [Bindable] private var brandsList:XMLListCollection; 
      [Bindable] private var citiesList:XMLListCollection; 
      [Bindable] private var shopsList:XMLListCollection; 
      [Bindable] public var gridList:XMLListCollection; 

      private var selectedCountry:int = 0; 
      private var selectedCountryId:int = 0; 
      private var selectedBrand:int = 0; 
      private var selectedCity:int = 0; 
      private var selectedBrandId:int = 0; 
      private var selectedCityId:int = 0; 

      private function sendData():void { 
       shopsService.send(); 
      } 

      private function shopsService_return(event:ResultEvent):void { 
       placesXML = XMLList(event.result); 
       brandsList = new XMLListCollection(placesXML.brands.brand); 
       citiesList = new  XMLListCollection(placesXML.countries.country[0].cities.city); 
       shopsList = new XMLListCollection(placesXML.shops.shop); 
       gridList = new XMLListCollection(); 
      } 

      private function onBrandboxChange(event:IndexChangeEvent):void { 
       selectedBrand = event.target.selectedIndex; 
       selectedBrandId = placesXML.brands.brand[selectedBrand].attribute("id"); 
       filterShops(selectedCountryId.toString(),selectedBrandId.toString(),selectedCityId.toString()); 
      } 

      private function onCityboxChange(event:IndexChangeEvent):void { 
       selectedCity = event.target.selectedIndex; 
       selectedCityId = placesXML.countries.country[selectedCountry].cities.city[selectedCity].attribute("id"); 
       filterShops(selectedCountryId.toString(),selectedBrandId.toString(),selectedCityId.toString()); 
      } 

      private function englandClick(event:MouseEvent):void 
      { 
       citiesList = new XMLListCollection(placesXML.countries.country[0].cities.city); 
       selectedCountry = 0; 
       selectedCountryId = 1; 
      } 

      private function scotlandClick(event:MouseEvent):void 
      { 
       citiesList = new XMLListCollection(placesXML.countries.country[1].cities.city); 
       selectedCountry = 1; 
       selectedCountryId = 2; 
      } 

      private function filterShops(countryId:String,brandId:String,cityId:String):void { 
       var xmlCountryId:String; 
       var indexOfBrandId:int; 
       var xmlCityId:String; 
       //outputLabel.text = countryId+"-"+brandId+"-"+cityId; 

       for (var i:int = 0; i < shopsList.length; i++) { 
        xmlCountryId = shopsList[i].attribute("country"); 
        xmlCityId = shopsList[i].attribute("city"); 

        if (xmlCountryId == countryId && xmlCityId == cityId) { 
         indexOfBrandId = shopsList[i].attribute("brands").toString().split(",").indexOf(brandId); 
         if (indexOfBrandId > -1) gridList.addItem(shopsList[i]); 
        } 
        outputLabel.text = shopsList[0].title; 
       } 
      } 

     ]]> 
    </fx:Script> 

    <s:List id="outputWindow" x="10" y="230" width="795" height="338" borderVisible="false" 
     dataProvider="{gridList}"> 
     <s:layout> 
      <s:TileLayout 
      requestedColumnCount="4" 
      requestedRowCount="2" 
      horizontalGap="2" 
      verticalGap="2"/> 
     </s:layout> 
     <s:itemRenderer> 
      <fx:Component> 
       <s:VGroup width="180" height="90"> 
        <s:Label styleName="item-title" text="{data.title}" /> 
        <s:Label color="#868686" fontFamily="pfHighwayRegular" fontSize="12" paddingBottom="-2" 
         paddingTop="-2" styleName="item-text" text="Tel: 0120 230 3777"/> 
        <s:Label styleName="item-text" text="Mail: [email protected]"/> 
        <s:Label styleName="item-link" text="Web: www.2012ltd.co.uk"/> 
       </s:VGroup> 
      </fx:Component> 
     </s:itemRenderer> 
    </s:List> 
    <s:Button x="6" y="8" label="England" click="englandClick(event)"/> 
    <s:Button x="125" y="8" label="Scotland" click="scotlandClick(event)" /> 
    <s:Button x="261" y="10" label="Wales"/> 
    <s:Button x="400" y="10" label="Ireland"/> 
    <s:ComboBox x="505" y="56" id="brandBox" dataProvider="{brandsList}" change="onBrandboxChange(event)" /> 
    <s:ComboBox x="659" y="56" id="cityBox" dataProvider="{citiesList}" change="onCityboxChange(event)" /> 
    <s:Label id="outputLabel" x="10" y="119" text="Label"/> 
</s:Application> 
+0

Hiya用戶,這是程序講的:)。因此,將組件放在一個內聯定義中,並將其定義在另一個文件中,這樣會稍微減少混淆,當您將這個實現添加到VGroup並實現IDropInListItemRenderer和IDataRenderer時。這意味着你將在渲染器中擁有一個數據屬性和一個listData屬性,數據將爲每個使用的渲染器分配一個列表元素(或重用),listData將獲得關於主列表和dataProvider中的數據索引等。 – shaunhusain

+0

還有兩件事要注意,我沒有看到gridList中填充了什麼東西?另外,如果您在XML中使用屬性而不是節點,則需要在屬性名稱前面使用@符號。 – shaunhusain

+0

我也會嘗試這種方式。 gridList使用addItem填充在filterShops函數中。它確實填充了列表,因爲我不會看到填充List組件的任何東西:)。屬性就是id,我不需要它們,因爲真正的數據在節點中。一旦我嘗試這樣做就會報告回來。 – geodeath

回答

0

所以,把你的組件出的是內聯定義和在另一個文件中定義它,這將使這是略少混亂,當你這樣做增加一個實現到VGroup並實現IDropInListItemRenderer和IDataRenderer。這意味着你將在渲染器中擁有一個數據屬性和一個listData屬性,數據將爲每個使用的渲染器分配一個列表元素(或重用),listData將獲得關於主列表和dataProvider中的數據索引等。

0

我認爲你需要在你的itemRenderer中引用你的List組件。實際上,對於任何內嵌項目渲染器,情況可能如此。試試這個:

<s:Label styleName="item-title" text="{parentDocument.data.title}" /> 

或本:

<s:Label styleName="item-title" text="{outerDocument.data.title}" /> 
+0

我只是嘗試了parentDocument的方式,雖然它不會給我一個錯誤了,它也不會顯示任何文字在標籤中)。我需要確定一切是否正常,因爲它不會給我任何錯誤。使用outerDocument仍然給我錯誤,儘管 – geodeath

+0

parentDocument指的是使用Component的MXML文件,在這裏顯示的上下文中,與應用程序相關的是「this」,不需要應用程序的數據,但您希望這個項目渲染器的數據......我不太確定outerDocument的含義,絕對採取實現這兩個接口的路徑,儘管你會感謝我,但事實證明你需要更多關於渲染器的上下文信息(它經常出現,我通常只是在我現在實現渲染器時執行此操作) – shaunhusain

相關問題