【问题标题】:flex doesn't seem to bind with custom actionscript objectflex 似乎没有与自定义 actionscript 对象绑定
【发布时间】:2009-05-25 14:57:21
【问题描述】:

我有一个自定义的 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");
    }  

但也没有运气。

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

【问题讨论】:

    标签: apache-flex actionscript-3 binding


    【解决方案1】:

    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 框架中最强大的工具之一,但如果使用不当会引起很多麻烦。特别是,当绑定“闲置”时,请注意内存泄漏和“意外更新”。

    【讨论】:

    • Kieren H - 这能解决您的问题吗?如果是,请标记为已回答!
    • 你是一个传奇人物 - 我遇到了很多绑定问题,你在这里的回答解释了很多发生的事情,以及为什么事情有时似乎随机不起作用。 GW
    • 我也应该详细说明绑定的内存泄漏影响。为了观察“右手边”的变化,绑定机制为右手边的对象添加了一个事件监听器——整个链中的每个对象。这些事件侦听器指向 绑定对象 (ChangeWatchers),因此,即使在您自己的对象消失后,这些事件侦听器也会保留在内存中。出于这个原因,我尝试始终为观察者(watcher = BindingUtils.bindProperty(...)) 保留一个引用,然后当我的对象离开以删除所有这些事件侦听器时 watcher.unwatch()
    【解决方案2】:

    这段代码:

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

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

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

    【讨论】:

      【解决方案3】:

      您是否尝试实现IEventDispatcher,或扩展EventDispatcher

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-26
        • 2011-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-20
        • 1970-01-01
        • 2018-01-13
        相关资源
        最近更新 更多