Flex s:DataGrid所有ItemRenderer都被触发

时间:2013-12-22 13:53:28

标签: flex datagrid itemrenderer

我不明白为什么当我们更改dataprovider上的数据时,会调用受影响列的所有itemRenderers?这是我的问题的一个小例子:

申请:

    <?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" creationComplete="application1_creationCompleteHandler(event)">

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

        private var _ac:ArrayCollection = new ArrayCollection();

        protected function application1_creationCompleteHandler(event:FlexEvent):void
        {
            var i:int = 10;

            while(i >= 0)
            {
                _ac.addItem({fieldA:Math.random() * 100, fieldB:Math.random() * 100});
                i--;
            }

            dg.dataProvider = _ac;
            dg.requestedRowCount = _ac.length;
        }

        protected function button1_clickHandler(event:MouseEvent):void
        {
            _ac.getItemAt(0)["fieldA"] = Math.random() * 100;
            _ac.getItemAt(0)["fieldB"] = Math.random() * 100;
            _ac.refresh();
        }

    ]]>
</fx:Script>

<s:layout>
    <s:VerticalLayout />
</s:layout>

<s:Button label="change data" click="button1_clickHandler(event)" />

<s:DataGrid id="dg">
    <s:columns>
        <s:ArrayList>
            <s:GridColumn dataField="fieldA" itemRenderer="MyItemRenderer" />
            <s:GridColumn dataField="fieldB" />


    </s:ArrayList>
        </s:columns>
    </s:DataGrid>

</s:Application>

myItemRenderer:

 <?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:Declarations>
        <s:Sequence id="myAnimation" duration="2000" target="{col}" >
            <s:Fade alphaFrom="0.0" alphaTo="1.0"/>
            <s:Fade alphaFrom="1.0" alphaTo="0.0"/>
        </s:Sequence>                   
    </fx:Declarations>

    <fx:Script>
        <![CDATA[

            private var _data:Object;

            override public function set data(value:Object):void
            {
                super.data = value;

                _data = value;

                if(null != _data)
                {
                    display();
                }
            }

            private function display():void
            {
                lblData.text = _data[column.dataField];
                myAnimation.play();
            }

        ]]>
    </fx:Script>

    <s:Rect top="-2" left="0" right="0" bottom="-2">
        <s:fill>
            <s:SolidColor id="col" color="0xFF0000" />
        </s:fill>
    </s:Rect>

    <s:Label id="lblData" top="9" left="7"/>

</s:GridItemRenderer>

我只想在受影响的单元格上播放动画,但每次都会触发每个单元格上的动画。我该如何编码呢?​​

1 个答案:

答案 0 :(得分:1)

回收所有这一切的原因是:您正在调用refresh方法,因此您明确要求所有这些回收。它将使应用于您的集合的所有排序和过滤器无效,因此数据网格中项目的所有位置都将失效,并且每个项目都将被回收。

所以你应该删除这个电话。之后,这样的事情应该做你期望的事情:

    private var colValue:String;

    override public function prepare(hasBeenRecycled:Boolean):void {
        if (data && colValue != data[column.dataField]) {
            colValue = data[column.dataField];
            lblData.text = colValue;
            myAnimation.play();
        }
    }

每次都会调用prepare方法,但只有在值实际发生变化时才会播放动画。