flex似乎没有与自定义actionscript对象绑定

时间:2009-05-25 14:57:21

标签: flex actionscript-3 binding

我有一个自定义actionscript对象,定义为可绑定多个公共属性。

[Bindable]
public class MyObject extends Object {   

    public var mobileNumber:String;
...

在我的mxml中,我有:

<mx:Script><![CDATA[
    import mx.binding.utils.BindingUtils;
    import org.test.MyObject;

    [Bindable]
    private var obj: MyObject = new MyObject();
]]></mx:Script>

<mx:Label text="Mobile Number" id="mobileNumberLabel"/>
<mx:TextInput id="mobileNumberText" text="{obj.mobileNumber}" />

<mx:LinkButton label="Load" id="loadButton" enabled="true" click="obj = obj.load();"/>
<mx:LinkButton label="Save" id="saveButton" enabled="true" click="obj.write();"/>

我的问题是,当我在手机号码字段中输入新值然后单击保存按钮时,键入的值不会被注销...即:

    public function write():void {
        var bytes:ByteArray = new ByteArray();
        trace("write - mobile:" + this.mobileNumber);

        bytes.writeObject(this);
        EncryptedLocalStore.setItem(KEY, bytes);
    }

我也试过加入:

    private function init():void {
        BindingUtils.bindProperty(mobileNumberText, "text", obj, "mobileNumber");
    }  

但也没有运气。

我可能在这里错过了一些简单的东西,但不确定它是什么。希望你能帮忙,谢谢。

3 个答案:

答案 0 :(得分:8)

tst的答案是正确的 - 绑定是单向的。我猜你已经知道了,因为你尝试在init()方法中设置反向绑定。

但是,init()方法存在两个问题。

首先,不清楚你在哪里放置init()方法,或者调用它的方法。

其次,你向后获得了方法参数。

我在这种情况下通常做的是使用mxml标签作为第一个响应者建议,或者如果我使用的是AS3代码,我会这样做:

private function onCreationComplete(event:Event):void
{
  BindingUtils.bindProperty(obj, "mobileNumber", mobileNumberText, ["text"]);
}

请注意以下几点:

1 / BindingUtils.bindProperty()是“左手边=右手边”。因此,它有点像写作

  obj.mobileNumber = mobileNumberText.text;

或者,更接近绑定类中“实际进行”的内容:

  obj["mobileNumber"] = mobileNumberText["text"];

2 / BindingUtils.bindProperty()实际上想要一个数组作为最后一个参数。这样你就可以在逻辑上做“链式属性”:

obj.mobileNumber = mobileNumbersGrid.selectedItem.text;

将是

BindingUtils.bindProperty(obj, "mobileNumber", mobileNumbersGrid,
    ["selectedItem", "text"]);

3 /最佳实践提示:如果您绑定的是一个属性链,其初始成员是您自己的属性(this),则将其写为:

BindingUtils.bindProperty(obj, "mobileNumber", this,
    ["mobileNumbersGrid", "selectedItem", "text"]);

这巧妙地处理了你的“右侧对象”this.mobileNumbersGrid实例本身被一个新的实例对象替换的情况。

4 /如果您重新分配obj(“左侧”),则需要为新的obj实例创建新的绑定。通常,您可以通过将本地obj属性转换为getter / setter对来执行此操作:

  public function get obj():MyObject
  {
    return _obj;
  }

  private var _obj:MyObject = new MyObject();

  public function set obj(value:MyObject):void
  {
    _obj = value;
    BindingUtils.bindProperty(_obj, "mobileNumber", mobileNumberText, ["text"]);
  }

(注意:要非常小心,你要从BindingUtils.bindProperty()中隐藏返回的值,这是一个ChangeWatcher实例,你可以用unwatch()来防止旧对象接收属性更改。

希望这会有所帮助。绑定是Flex框架中最强大的工具之一,但如果使用不当会导致很多麻烦。特别是,当绑定“闲置”时,请注意内存泄漏和“意外更新”。

答案 1 :(得分:1)

此代码:

<mx:TextInput id="mobileNumberText" text="{obj.mobileNumber}" />

在obj.mobileNumber和mobileNumberText.text之间进行单向绑定。你需要的是一个额外的反向绑定 - 在代码中添加以下行,它将起作用:

<mx:Binding source="mobileNumberText.text" destination="obj.mobileNumber"/>

答案 2 :(得分:0)

您是否尝试实施IEventDispatcher或扩展EventDispatcher

绑定通过调度PropertyChangeEvents来工作,所以这可能是问题所在? 另外,我不确定,绑定是否适用于变量,或者它们是否需要属性(getter / setter)。

您应该尝试使用-keep-generated-actionscript进行编译,看看生成的代码是否有意义,即调度任何事件,如果访问该变量...