【问题标题】:Flex s:DataGrid all ItemRenderer are firedFlex:DataGrid 所有项目渲染器都被触发
【发布时间】:2013-12-22 13:53:27
【问题描述】:

我不明白为什么当我们更改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>

我的项目渲染器:

 <?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>

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

【问题讨论】:

  • A) 使用强类型数据模型,B) 如果实际数据没有改变,则在数据设置器中尽早返回
  • @drkstr1 : A) 这只是一个例子。 B)它不会解决我的问题。我已经更改了我的项目渲染器代码,但现在,在更新另一个数据时,它会在效果结束之前被回收。我正在寻找一种方法来防止我的项目渲染器在其生效期间被回收。

标签: apache-flex datagrid itemrenderer


【解决方案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 方法仍然每次都会被调用,但是只有当值实际发生变化时才会播放动画。

【讨论】:

  • 非常感谢!!前几天我对代码进行了一些修改以优化性能,但我不记得我删除了数据对象上的 Bindable 元数据以改用刷新方法(-> 错误尝试)。现在它的工作就像一个魅力再次感谢点刷新方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
  • 2018-01-18
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
相关资源
最近更新 更多