Question

I've got a bindable model class (lets call it myModel) with two properties, label and value. The value gets updated frequently, so it is marked as bindable. Works fine so far, the data is updated and the standard property change event is dispatched.

Now I have to make an ArrayCollection from the object instances of this model to use it as a data provider in a data group. The data gets then passed to a custom itemRenderer in which I access the myModel properties via data.label and data.value.

The only problem I've got now is that the myModel value property doesn't change any more (I suppose because I stored the objects in the ArrayCollection).

The ArrayCollection is marked bindable as well btw, because new object instances of myModel can be added during runtime.

Is there any way to make this work? Any help regarding this would be much appreciated!

Edit: I almost forgot, the value object in the myModel class is updated by another bindable class. Yes, I know that's bonkers but that's why I'm here, to get some input on a simpler (and in fact working) way to solve this problem.

2nd edit: Allright guys, a little bit of code to illustrate the issue;

Lets start with the first bindable class;

[Bindable]
public class FirstClass
{
   public var name:String;
   public var firstValue:Number;
   public var secondValue:Number;
   public var thirdValue:Number;

   public function FirstClass()
   { }
 }

The values (first to third) get updated by a controller class. So far so good. Now to the second model class (for matters of consistency, lets keep the MyClass name)

[Bindable]
public class MyClass
{
   public var label:String;
   public var value:Number;

   public function FirstClass()
   { }
 }

These are the two model classes. Background behind this is that I need a String value (a label) for each property of an instance of FirstClass. I'd like to make this simpler, so I'm really not settled on this "solution" cough ;).

Anyhow, we've got the two models, now to my .mxml class;

[Bindable] private var firstClassInstance:FirstClass;

I create a new ArrayCollection and add objects like this; myArrayCollection.addItem(new MyClass("This is a label", firstClassInstance.firstValue));

And again, the DataGroup uses this ArrayCollection as a data provider.

As we already established (thank you @Windowns), the ArrayCollection looks only for objects being added or removed, not property changes of these objects.

Was it helpful?

Solution 4

I took Amy's advice and researched a little further on the itemUpdated method. Turns out, the solution was right there.

See here: http://flex4examples.wordpress.com/2009/08/28/1st/

I applied this methodology (with little variations) to my code and it works quite good. Performance on the iPad2 is good and so is the memory usage of my component.

Let's hope that Amy is fine with this solution as well. Fingers crossed. ;)

OTHER TIPS

Call itemUpdated on your ArrayCollection when you update a "piece" of an item stored in it.

There could be many issues with binding. Please post code to help us see what is happening. Here are some "high level" things to watch out for that might answer your question

When using an bindable arraycollection of objects, it's important to note that the binding for the arraycollection only looks at each object instance and if it's added or removed from the collection. It will not know about any property changes that occur to your object. Commonly when you use an itemrenderer, the properties are bound to display elements. Like maybe the "value" property bound to a label in the itemrenderer. Now when your object instance (myModel) changes it's "value" property the label should pick it up. Also note that you need to mark any properties you intend to bind to visual elements with the [Bindable] meta-tag.

public class myModel
{
    [Bindable]
    public var label:String;
    [Bindable]
    public var value:String; 

    public function myModel() {}
}

Answer after code post:

When you do the following:

myArrayCollection.addItem(new MyClass("This is a label", firstClassInstance.firstValue));

You are taking the value of firstClassInstance.firstValue and supplying it as a hard value (as in not passing value by reference). So if you do the following:

myArrayCollection.getItemAt(addedClassIndex).value = 5;

Will not cause any changes to be noted in the firstClassInstance.firstValue as there is no "referening information" stored. We are only working with the basic type of Number which is never passed by reference like all other objects are in Flex.

Maybe try this:

[Bindable]
public class MyClass
{
    public var label:String;

    [Bindable]   //might be redundant due to global [Bindable] flag, been a while since i've used a global one
    public function get value():Number{
        return m_objRef.firstValue;
    }
    public function set value(value:Number):void{
        m_objRef.firstValue = value;
    }

    private var m_objRef:FirstClass;

    public function MyClass(_label:String, _valueObj:FirstClass) {
        m_objRef = _valueObj;
        label = _label;
    }
}

Allright guys (and gals ;)) after two hours of messing around with BindingUtils, I finally found the solution to my problem. The two model classes can remain the way they are, so passing the instance of FirstClass isn't necessary. Simply binding the value properties of FirstClass to the value field of MyClass works as expected and the values in the ArrayCollection get updated as well.

So the solution;

myClassObject = new MyClass();
myClassObject.label = "This is a label";
BindingUtils.bindProperty(myClassObject, "value", firstClassObject, "firstValue");

And then simply add the myClassObject to the ArrayCollection.

Keep in mind that all the code here is pseudo code, so never mind any typos.

Still, @Windowns suggesting with passing the FirstClass object to the MyClass will be incorporated into my final solution as it makes switching between properties a lot easier (FirstClass has got lots of them, not just the 4 in my first post). Many thanks for that!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top