سؤال

Hello to whomever wishes to help me.

I'm trying to implement this example: http://ramblingdeveloper.com/ramblings/2011/9/24/creating-a-flex-spark-list-of-checkbox-bound-to-xml-dataprov.html

My example is fairly the same with a few small differences which I modified the whole code accordingly.

My MXML Application:

<?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" minWidth="955" minHeight="600">
<fx:Declarations>
<fx:XML format="e4x" id="namesXML">
    <people>
        <person>
            <name>Leon</name>
        </person>
        <person>
            <name>Mathilda</name>
        </person>
        <person>
            <name>Stansfield</name>
        </person>
        <person>
            <name>Benny</name>
        </person>
    </people>
</fx:XML>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
    <![CDATA[
        import mx.collections.XMLListCollection;

        var temp:XMLListCollection = new XMLListCollection(namesXML.children());
    ]]>
</fx:Script>
<s:List itemRenderer="CheckBoxItemRenderer"
        dataProvider="{temp}"/>

and my MXML ItemRenderer:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" 
            autoDrawBackground="true">

<s:CheckBox label="{data.person.name}"/>

</s:ItemRenderer>

I keep getting a Null Object Reference and have been messing around with where I think the problem is:

<s:CheckBox label="{data.person.name}"/>

Which is how I'm accessing my XML data, but I'm not 100% sure since XML and XML traversal isn't my strongest point. Any small insight would help while I sit and keep tweaking it on my end for a breakthrough.

EDIT: Fixed the ItemRenderer code, was missing the closing tag. EDIT #2: The name of my ItemRenderer file is CheckBoxItemRenderer like the example has.

هل كانت مفيدة؟

المحلول

Partial answer - since namesXML is declared in the <fx:Declarations> section, it is a child of your main application, and isn't instantiated until later (when all the children are created).

If you want to leave namesXML defined as you have, I'd suggest adding a creationComplete handler and setting temp at that time:

<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"
                   creationComplete="doInit()">

    <fx:Script>
        <![CDATA[
           import mx.collections.XMLListCollection;

            var temp:XMLListCollection;

            protected function doInit():void {
                temp = new XMLListCollection(namesXML.children());
            }
        ]]>
   </fx:Script>

Another problem is that temp needs to be marked as Bindable - otherwise, when it gets set the changes won't cause the List to redisplay.

Finally, the XMLNode items in temp are already person nodes, so you only need to specify data.name in the item renderer:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" 
            autoDrawBackground="true">

<s:CheckBox label="{data.name}"/>

</s:ItemRenderer>

نصائح أخرى

This isn't quite an answer; but it is too big for a comment. To help debug; instead of using Binding in the ItemRenderer use the dataChange event:

<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" 
            autoDrawBackground="true" dataChange="onDataChange()>

<fx:Script>
<[[
 protected function onDataChange():void{
   // if data isn't defined; just perform a return here
   if(!data){ return }
   // try a lot of traces to see what comes out
   trace(data);
   trace(data.name);
   trace(data.person);
   trace(data.person.name);
   // etc.,. etc..
   var checkBoxLabel :String = data.person.name;
   check.label = checkBoxLabel;
 }
]]>
</fx:Script>

<s:CheckBox id="check" />

</s:ItemRenderer>

I am not an expert at XML parsing either. I have found that watch variables in the Flash Builder Debug panel are inconsistent / unhelpful in drilling down into XML; so the trace statements are the way to go.

IF I had to guess; the data is equal to a single person, like this:

<person>
    <name>Benny</name>
</person>

So, doing data.person is probably redundant and tries to drill down too far resulting in the null value. data.name seems more likely; in my mind.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top