2013-12-22 94 views
0

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

应用:

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

我只想对受影响的电池,但每次放动画,在每个单元动画被解雇。我该如何编码?

+0

A)使用强类型数据模型和B)如果实际数据没有改变,在数据设置器的早期返回 – drkstr1

+0

@ drkstr1:A)这只是一个例子。 B)它不会解决我的问题。我已经更改了我的项目渲染器代码,但是现在,它会在更新另一个数据时发生效果结束时再循环。我正在寻找一种方法来防止我的项目渲染器在其效果期间进行回收。 –

回答

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方法仍然会被调用每一次,但是当值实际上有没有改变你的动画才会播放。

+0

非常感谢!前几天,我对代码进行了一些修改以优化性能,并且我不记得我删除了数据对象上的Bindable元数据,而是使用refresh方法( - > bad try)。现在它像一个魅力工作再次感谢点刷新方法。 –