无法从Flex应用程序中的数据提供者中获取数据

时间:2012-01-26 18:09:48

标签: flash flex list builder itemrenderer

我正在为一个网站构建一个应用程序,该应用程序将过滤带有一些产品/品牌的商店,并在List组件中显示结果。我一直在加载数据,将品牌/国家/城市放在组合框中,以便用户可以过滤他想要查看的国家和城市以及哪个品牌。直到现在都没问题。我的问题是,虽然数据提供者在将一些值硬编码到我用于每个条目的项目渲染器的标签时应该工作,但我无法从数据提供者那里获得真实数据..您将在下面的代码中看到,在VGroup组件中(我用于列表中的每个商店)有4个标签,其中3个是硬编码的,只是为了看它的工作原理。其中一个标签是试图从xml文件中获取真实数据,那就是我停下来的地方。在我看过的所有教程(以及文档中)中,每个人都会点击“data.XYZ”,其中XYZ是要获取的属性或节点的名称。在我的情况下执行相同操作只会返回错误“1120:访问未定义的属性数据。”。我究竟做错了什么?我花了几个小时来迭代数百个flex的例子,包括新版本和旧版本,我不知道该怎么做。当剩下的都进去的时候,坚持这最后一件小事真的很神经!看看代码,让我知道如果我做错了什么或我错过了什么!发布以下代码。还有一个xml文件,但它正确加载,不同的xmlLists DO存储了正确的节点,所以我不认为它需要发布,除非你不这么认为。每个商店的xml节点都是“标题”,“电话”,“邮件”,“城市”,我不得不试图获得标题。最重要的功能是filterShops one,然后是整个list和itemrenderer块。

<?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: info@2012ltd.co.uk"/>
                    <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>

2 个答案:

答案 0 :(得分:0)

我认为您需要在itemRenderer中引用List组件。实际上,对于任何内联项呈示器都可能是这样。试试这个:

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

或者这个:

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

答案 1 :(得分:0)

因此,将您的组件作为内联定义并在另一个文件中定义,这将使这一点稍微减少混乱,当您这样做时,将实现添加到VGroup并实现IDropInListItemRenderer和IDataRenderer。这意味着您将在渲染器中拥有data属性和listData属性,对于每个使用(或重复使用)渲染器的渲染器,数据将为其分配一个列表元素,listData将具有有关主列表和dataProvider等中的数据索引。