Search code examples
apache-flexflex4flexbuilderitemrendererflex4.5

TypeError when using ItemRendering and a spark GridColumn


I am rendering the GridColumns of spark DataGrid as follows:

<?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" 
               initialize="doSend()">
    <fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
        <s:HTTPService id="xmlFromDatabase" method="GET"
                       result="resultHandler(event)" showBusyCursor="true"
                       url="http://localhost:81/PHP-Pro/mys.php"/>
    </fx:Declarations>
    <fx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.core.ClassFactory;
        import mx.rpc.events.ResultEvent;

        import spark.skins.spark.DefaultItemRenderer;
        import spark.utils.DataItem;
        [Bindable]
        private var datalist:ArrayCollection;
        private var mTimer:Timer = new Timer(1000,10);

        private function Countsec(e:TimerEvent):void
        {
            lbltime.text=e.target.currentCount;
        }
        private function Comple(e:TimerEvent):void
        {
            lbltime.text="Time Complete";
        }
        private function resultHandler(event:ResultEvent):void{
            mTimer.start();
            mTimer.addEventListener(TimerEvent.TIMER,Countsec);
            mTimer.addEventListener(TimerEvent.TIMER_COMPLETE,Comple);
            datalist = event.result.data.row;
        }
        public function doSend():void {
            xmlFromDatabase.url = "http://localhost:81/PHP-Pro/mys.php";
            xmlFromDatabase.send(); 
        }

        private function FItem_renderer(item:Object, column:GridColumn):ClassFactory{
            //the main logic is here when the value of GridColumn is="SBI" i 
            //should call my user defined renderer else default render
            if (item.FNo=="SBI"){//not working here
                return new ClassFactory(FlightRenderer);    
            } else {
                return new ClassFactory(DefaultItemRenderer);
            }   
        }
        ]]>
    </fx:Script>
    <s:Panel left="20" top="20" horizontalCenter="true"
             title="Просмотр рейсов" verticalCenter="true">
        <s:layout>
            <s:FormLayout/>
        </s:layout>
        <s:mxmlContentFactory>
            <s:DataGrid id="dg" x="10" y="10" width="708" height="272" color="#01064D"
                        dataProvider="{datalist}" fontFamily="tahoma">
                <s:columns>
                    <s:ArrayList>
                        <s:GridColumn dataField="data" headerText="Дата" itemRendererFunction="FItem_renderer"/>
                        <s:GridColumn dataField="FNo" headerText="№рейса" itemRendererFunction="FItem_renderer"/>
                        <s:GridColumn dataField="name_ru" headerText="Город" itemRendererFunction="FItem_renderer"/>
                        <s:GridColumn dataField="AirCraft" headerText="ВС" itemRendererFunction="FItem_renderer" />
                        <s:GridColumn dataField="FTime" headerText="Время" itemRendererFunction="FItem_renderer"  />
                        <s:GridColumn dataField="Stat" headerText="Статус" itemRendererFunction="FItem_renderer"/>
                    </s:ArrayList>
                </s:columns>
            </s:DataGrid>
        </s:mxmlContentFactory>
    </s:Panel>
    <s:Label id="lbltime" x="41" y="347" fontSize="30" fontWeight="bold" text="Label"/>
</s:Application>

And renderer class [FlightRenderer.mxml]:

<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:mx="library://ns.adobe.com/flex/mx"
                    clipAndEnableScrolling="true">
    <fx:Script>
    <![CDATA[
        override public function prepare(hasBeenRecycled:Boolean):void {
            lblData.text = data[column.dataField]
        }
    ]]>
    </fx:Script>
    <s:Rect top="0" bottom="0" right="0" left="0">
        <s:fill>
            <s:SolidColor color="#E0E0E0" alpha="0.5"/>
        </s:fill>
    </s:Rect>
    <s:Label id="lblData" top="9" left="7" color="0x505050" alpha="0.5"/>
</s:GridItemRenderer>

When I run this app the following error occurs:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at spark.components::Group/addElement()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\Group.as:1342]
    at spark.components.gridClasses::GridLayout/createTypicalItemRenderer()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\GridLayout.as:748]
    at spark.components.gridClasses::GridLayout/updateTypicalCellSizes()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\GridLayout.as:883]
    at spark.components.gridClasses::GridLayout/measure()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\GridLayout.as:444]
    at spark.components.supportClasses::GroupBase/measure()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\supportClasses\GroupBase.as:1148]
    at mx.core::UIComponent/measureSizes()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:8496]
    at mx.core::UIComponent/validateSize()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:8420]
    at spark.components::Group/validateSize()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\Group.as:1012]
    at mx.managers::LayoutManager/validateSize()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:665]
    at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:792]
    at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1180]

I know that I am misusing overriding defaultItemRender and don't know what to declare as it's input arguments:

private function FItem_renderer(item:Object, column:GridColumn):ClassFactory

and how can I check GridColumn values in this function?


Solution

  • Without seeing what your server is returning, try this. Null safe the if statement, for before the data provider is initialized. Also, you might want to change DefaultItemRenderer to DefaultGridItemRenderer,

    private function FItem_renderer(item:Object, column:GridColumn):ClassFactory{
                    //the main logic is here when the value of GridColumn is="SBI" i 
                    //should call my user defined renderer else default render
                    if (item && item.FNo=="SBI"){//not working here
                        return new ClassFactory(FlightRenderer);    
                    }else
                    {
                        return new ClassFactory(DefaultGridItemRenderer);
                    }   
                }