Search code examples
xmlapache-flexmobiledataprovider

Flex Hero: Loading XML data works, but List is not updated


I have this Flex 4.5 (Burrito) Mobile project:

alt text

It consists of 2 files - the TextXML.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:MobileApplication 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:components="spark.components.*" 
    firstView="views.Home">
</s:MobileApplication>

and the Home.mxml with 1 Button, 1 List and 1 HTTPService:

<?xml version="1.0" encoding="utf-8"?>
<s:View 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:components="spark.components.*" 
    title="Home">

    <fx:Script>
        <![CDATA[
            import mx.collections.*;
            import mx.events.*;
            import mx.rpc.events.*;
            import mx.utils.*;
            import spark.events.*;

            [Bindable]
            public var myColl:XMLListCollection = new XMLListCollection();

            public function srvResult(event:ResultEvent):void {
                trace(ObjectUtil.toString(event.result));
                myColl.source = event.result.pref.user.money;
                myList.dataProvider = myColl;
            }
            public static function myLabelFunc(item:Object):String {
                return item.yw;             
            }
            public static function myMessageFunc(item:Object):String {
                return item.max;
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <s:HTTPService 
            id="httpSrv" 
            url="http://preferans.de/user-xml.php?id=OK123195454365" 
            resultFormat="e4x" 
            result="srvResult(event)" 
            fault="trace(event.fault.message)" />
    </fx:Declarations>

    <s:navigationContent>
        <s:Button label="Load XML" click="httpSrv.send()"/>
    </s:navigationContent>

    <s:List id="myList" 
            top="0" bottom="0" left="0" right="0" 
            dataProvider="{myColl}">
        <s:itemRenderer>
            <fx:Component>
                <s:MobileIconItemRenderer 
                    labelFunction="Home.myLabelFunc"
                    messageFunction="Home.myMessageFunc" >
                </s:MobileIconItemRenderer>
            </fx:Component>
        </s:itemRenderer>
    </s:List>
</s:View>

When I run my app in the debugger (so that I can see the trace output in the console) and click the "Load XML" button, then I see that XML data is loading ok from my PHP script:

<pref>
  <user id="OK123195454365" first_name="Dmitry"
   city="Moscow" money="8815" medals="1">
    <money yw="2011-01" max="8815" user="8815"/>
    <money yw="2010-52" max="6380" user="1545"/>
    <money yw="2010-51" max="8797" user="2094"/>
    <money yw="2010-50" max="8446" user="2080"/>
  </user>
</pref>

But the List unfortunately stays empty.

I have a feeling that a minor thing is missing here, maybe an event should be sent to the List? I've tried reassigning its dataProvider as you can see above, but it doesn't help me...

Thank you! Alex


Solution

  • There are several issues in your code :

    1. event.result is already pointing to the root node of the XML, so you don't need to call event.result.pref.
    2. You should use the @ syntax to get XML attributes values.
    3. You don't need to make your label functions static if you want to access them from an inline ItemRenderer. You should use the outerDocument property. The best practice is to create a new ItemRenderer mxml and communicate with its parent via events.

    The following code should work :

    <?xml version="1.0" encoding="utf-8"?>
    

    <fx:Script>
        <![CDATA[
            import mx.collections.*;
            import mx.events.*;
            import mx.rpc.events.*;
            import mx.utils.*;
    
            import spark.events.*;
    
            [Bindable]
            public var myColl:XMLListCollection = new XMLListCollection();
    
            public function srvResult(event:ResultEvent):void {
                var xml:XML = event.result as XML; 
                myColl = new XMLListCollection(new XMLList(xml.user.money));
            }
            public function myLabelFunc(item:Object):String {
                return item.@yw;             
            }
            public function myMessageFunc(item:Object):String {
                return item.@max;
            }
        ]]>
    </fx:Script>
    
    <fx:Declarations>
        <s:HTTPService 
            id="httpSrv" 
            url="test.xml" 
            resultFormat="e4x" 
            result="srvResult(event)" 
            fault="trace(event.fault.message)" />
    </fx:Declarations>
    
    <s:navigationContent>
        <s:Button label="Load XML" click="httpSrv.send()"/>
    </s:navigationContent>
    
    <s:List id="myList" 
            top="0" bottom="0" left="0" right="0" 
            dataProvider="{myColl}">
        <s:itemRenderer>
            <fx:Component>
                <s:MobileIconItemRenderer 
                    labelFunction="{outerDocument.myLabelFunc}"
                    messageFunction="{outerDocument.myMessageFunc}" >
                </s:MobileIconItemRenderer>
            </fx:Component>
        </s:itemRenderer>
    </s:List>