在可绑定的Arraycollection中侦听可绑定属性

时间:2011-12-05 16:31:31

标签: flex mobile itemrenderer arraycollection bindable

我有一个可绑定的模型类(让我们称之为myModel),它有两个属性,label和value。该值经常更新,因此标记为可绑定。 到目前为止工作正常,数据更新并调度标准属性更改事件。

现在我必须从此模型的对象实例创建一个ArrayCollection,以将其用作数据组中的数据提供程序。然后将数据传递给自定义的itemRenderer,我在其中通过data.label和data.value访问myModel属性。

我现在唯一的问题是myModel值属性不再发生变化(我想因为我将对象存储在ArrayCollection中)。

ArrayCollection被标记为可绑定以及btw,因为myModel的新对象实例可以在运行时添加。

有没有办法让这项工作?任何有关这方面的帮助将非常感谢!

编辑:我差点忘了,myModel类中的value对象由另一个可绑定类更新。是的,我知道那些疯子,但这就是我在这里的原因,以更简单(实际上是工作)的方式来解决这个问题。

第二次编辑:好的家伙,一些代码来说明这个问题;

让我们从第一个可绑定类开始;

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

   public function FirstClass()
   { }
 }

值(第一到第三)由控制器类更新。到现在为止还挺好。 现在到第二个模型类(为了保持一致性,让我们保持MyClass名称)

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

   public function FirstClass()
   { }
 }

这是两个模型类。这背后的背景是我需要FirstClass实例的每个属性的String值(标签)。我想让这更简单,所以我真的没有解决这个"解决方案" 咳嗽;)。

无论如何,我们已经有两个模型,现在我的.mxml类;

[Bindable] private var firstClassInstance:FirstClass;

我创建一个新的ArrayCollection并添加这样的对象;      myArrayCollection.addItem(new MyClass("这是一个标签",firstClassInstance.firstValue));

同样,DataGroup使用此ArrayCollection作为数据提供者。

正如我们已经建立的那样(感谢@Windowns),ArrayCollection只查找被添加或删除的对象,而不是这些对象的属性更改。

4 个答案:

答案 0 :(得分:1)

绑定可能存在许多问题。请发布代码以帮助我们了解正在发生的事情。以下是一些需要注意的“高级”内容,可能会回答您的问题

当使用可绑定的对象数组时,重要的是要注意,arraycollection的绑定只查看每个对象实例以及是否从集合中添加或删除它。它不会知道您的对象发生的任何属性更改。通常,当您使用itemrenderer时,属性将绑定到显示元素。就像绑定到itemrenderer中的标签的“value”属性一样。现在,当您的对象实例(myModel)更改它的“value”属性时,标签应该将其拾取。另请注意,您需要使用[Bindable]元标记标记要绑定到可视元素的任何属性。

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

    public function myModel() {}
}

在代码发布后回答:

执行以下操作时:

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

您正在获取firstClassInstance.firstValue的值并将其作为硬值提供(如不通过引用传递值)。因此,如果您执行以下操作:

myArrayCollection.getItemAt(addedClassIndex).value = 5;

不会在firstClassInstance.firstValue中记录任何更改,因为没有存储“引用信息”。我们只使用基本类型的Number,它永远不会通过引用传递,就像所有其他对象都在Flex中一样。

也许试试这个:

[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;
    }
}

答案 1 :(得分:1)

更新存储在其中的项目的“片段”时,在ArrayCollection上调用itemUpdated。

答案 2 :(得分:0)

好人(和gals;))经过两个小时的BindingUtils搞砸后,我终于找到了解决问题的方法。 这两个模型类可以保持原样,因此不需要传递FirstClass实例。 只需将FirstClass的value属性绑定到MyClass的value字段就可以正常工作,并且ArrayCollection中的值也会更新。

所以解决方案;

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

然后只需将myClassObject添加到ArrayCollection。

请记住,这里的所有代码都是伪代码,所以不要介意任何拼写错误。

但是@Windowns建议将FirstClass对象传递给MyClass将被合并到我的最终解决方案中,因为它使得属性之间的切换变得更加容易(FirstClass有很多它们,而不仅仅是我第一篇文章中的4)。非常感谢!

答案 3 :(得分:0)

我接受了Amy的建议,并对itemUpdated方法进行了进一步的研究。事实证明,解决方案就在那里。

见这里:http://flex4examples.wordpress.com/2009/08/28/1st/

我将这种方法(几乎没有变化)应用到我的代码中,它的效果非常好。 iPad2的性能很好,我的组件的内存使用情况也是如此。

让我们希望Amy对这个解决方案也很好。手指交叉。 ;)