views:

242

answers:

2

ok guy I really need you super brain on this, I had pull out all my hair now, I just want to throw the towel on this one, ok, I have an itemrender component, which you can see below

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" horizontalScrollPolicy="off"
   creationComplete="hbox1_creationCompleteHandler(event)">
 <mx:Script>
  <![CDATA[
   import events.ColorsEvent;

   import mx.binding.utils.BindingUtils;
   import mx.binding.utils.ChangeWatcher;
   import mx.events.ColorPickerEvent;
   import mx.events.FlexEvent;
   import mx.utils.ObjectProxy;

   import utils.BindingUniform;

   private var _op:ObjectProxy;
   private var cw:ChangeWatcher;

   public function get value():String
   {
    return data.color;
   }

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

   protected function cp_changeHandler(event:ColorPickerEvent):void
   {
    _op[data.id] = event.color;
   }

   protected function hbox1_creationCompleteHandler(event:FlexEvent):void
   {
    if(_op == null){
     _op = BindingUniform.op;
     cw = BindingUtils.bindSetter(dispatchColorChange, _op, data.id);
    }
   }

   protected function dispatchColorChange(color:uint):void
   {
    cp.selectedColor = color;
    dispatchEvent(new ColorsEvent("colorChanged", color, data.id, true, true));
   }

  ]]>
 </mx:Script>
 <mx:Text width="145"><mx:text>{data.value}</mx:text></mx:Text>
 <mx:ColorPicker id="cp" dataProvider="{parentDocument.colorsDP}" 
     valueCommit="{data.color = cp.selectedColor}"
     change="cp_changeHandler(event)" editable="false"/>
 <mx:Label id="colorLb" text="{cp.selectedItem.label}"/>
</mx:HBox>

the idea is when I change a color in one of the colorpicker then the change event must change a dynamic variable in my _op objectProxy object.

Ok when I scroll the list the colors remains in their respective colorpicker, which is ok, my problem comes in the binding, when the itemRender creationcomplete event fire, I make a bindsetter to the variable so I can dispatch an event when the property change.

The reason why I'm need the bind is because some times the user will load a previous saved model and I want the variables to remain bind so the colorpicker will select the color correctly, hope make sense.

Ok the thing is the first visible rows work just ok, but when I scroll the list, and try to change the color the color change in the colorpicker but my bind is gone, and if I scroll back to the top the first ones also aren't bind no more, I really don't know what else to do, I'm just hopping somebody has done something similar or just have the solution to this, please help me if you can, I really need it, I think my brain is going to explode, why binding is so hard in Flex? thanks!!!

+1  A: 

An itemRenderer should not reach outside itself to pull in data and especially not set values or participate in bindings or events. It should only act on the data passed to it. It can read values out of data or set values on data which can then be broadcast out to other components.

Programming this way, making your itemRenderer components fully encapsulated little black boxes, will greatly simplify development and generally work much better and avoid hard-to-find-and-debug problems like memory leaks and dangling item renderer references which can respond to evens even after you've long since thought they vanished.

Sam
A: 

I only glanced through your code to see if there were poor practices with itemRenderers, and I have two suggestions. First, as Sam mentioned, make your renderer a stand-alone component that doesn't depend upon your objectProxy object. Use events to make changes to make model-related changes.

Second, and more importantly, this line is a killer:

cp.selectedColor = data.color;

replace it with "value.color"

jeremym
mmm, ok I wil do it thanks for your reply and yes I agree with both, I change my design and now I'm able to bind, thanks!!
goseta