2013-12-22 36 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)。現在它像一個魅力工作再次感謝點刷新方法。 –