24

我有一个对象,其中包含十几个要绑定到表单元素的字段,以便我可以使用该对象将数据发送回服务器以进行保存。

我的容器对象的定义:

private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:Object = emptyLink;

currentLink在运行时分配给 ArrayCollection 中的特定索引,我只是将该emptyLink对象用于初始化目的,主要是。

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
    <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
        <mx:TextInput id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" />
        <mx:TextInput id="trigger2" width="100%" textAlign="left" text="{currentLink.trigger2}" />
        <mx:TextInput id="trigger3" width="100%" textAlign="left" text="{currentLink.trigger3}" />
        <mx:TextInput id="trigger4" width="100%" textAlign="left" text="{currentLink.trigger4}" />
        <mx:TextInput id="trigger5" width="100%" textAlign="left" text="{currentLink.trigger5}" />
    </mx:VBox>
</mx:Panel>

当然,这编译并显示得很好,但是每个实例都有运行时警告:

警告:无法绑定到类“Object”上的属性“trigger1”(类不是 IEventDispatcher)警告:无法绑定到类“Object”上的属性“trigger2”(类不是 IEventDispatcher)警告:无法绑定到类“Object”上的属性“trigger3”(类不是 IEventDispatcher)警告:无法绑定到类“Object”上的属性“trigger4”(类不是 IEventDispatcher)警告:无法绑定到类上的属性“trigger5” “对象”(类不是 IEventDispatcher)

并且当字段更改currentLink时,对象不会更新。TextInput

显而易见的答案是我的对象需要是实现IEventDispatcher. 该答案没有告诉我的是实现该接口的细节(需要什么?什么不是?),以及是否有更简单的方法来做到这一点——比如一个内置类,它很乐意接受我的自定义属性并允许对于绑定,我不必担心实现接口的细节。

这样的类存在吗?如果不是,那么完成这项任务的最低限度和/或公认标准是什么?

4

7 回答 7

16

您需要使用 ObjectProxy (正如 Chetan 提到的) - 但您还需要使用 valueCommit 将您在输入中输入的文本返回到您的对象中:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.utils.ObjectProxy;
              private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);


private function handleClick():void
{
    trace(currentLink.trigger1);
}
]]>
</mx:Script>

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
        <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput  id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" valueCommit="{currentLink.trigger1 = trigger1.text;}"/>

                <mx:Button label="Click" click="handleClick()"/>
        </mx:VBox>
</mx:Panel>        

</mx:WindowedApplication>
于 2009-05-29T22:01:03.770 回答
9

Object不分派事件。尽管您已将变量设为 Bindable,但currentLink无法绑定该变量所引用的对象的属性。

改为使用ObjectProxy

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);
于 2009-05-29T21:58:07.833 回答
5

您首先要知道的是 Flex 3 中的绑定不是双向的。绑定表达式将确保如果绑定表达式的源 (currentLink.trigger1) 发生更改,则目标 (TextInput) 将收到更改通知并相应地更新。如果您希望绑定朝另一个方向发展,至少有两种方法可以做到这一点:

  1. 使用 mx:Binding 标记将 TextInput.text 引导回对象
  2. 改用 BindingUtils 以编程方式执行此操作。

在 Flex 4 中,他们为双向绑定 @{some.binding.expression} 引入了一种新语法,但在 Flex 3 中不可用。

第二部分:您收到的错误是因为您绑定到“通用”原型对象。当您将 [Bindable] 元数据标记应用于属性或类时,MXMLC 编译器会生成 AS 代码,其中包括使用绑定实用程序和属性更改观察程序来进行绑定。但是,您不能让原型对象执行此操作,因为它是内置的。您可以创建一个可绑定的自定义 ActionScript 类(或具有可绑定的某些属性)。MXMLC 编译器将生成一个实现 IEventDispatcher 并因此支持绑定的类。这具有比原型对象更快的优点,并且还为您提供编译时检查,即如果您引用无效属性,您将收到编译器错误。

另一种选择是按照其他 SO 成员的建议将您的原型包装在 ObjectProxy 中。

于 2009-05-29T22:00:01.603 回答
3

只是关于如何在更大的项目中找出有问题的代码的提示 - 在两者上设置断点

trace("warning: unable to bind to property '"

SDK 的 PropertyWatcher 类中的行(Navigate > Open Type > ...)。Stacktrace 然后将帮助您找到保存损坏绑定的 ui 组件。

于 2013-11-19T01:39:54.213 回答
2

一般来说,你得到“无法绑定到类上的属性 foo 的原因是因为你缺少 foo 的 getter 或 setter。你可以将 foo 限定为公共变量,(尽管这会破坏封装)

所以你需要这两个来让它消失:

public function set foo (o:FooObject) : void {
...
}

或者

public function get foo() : FooObject {
...
}
于 2010-07-29T09:49:09.037 回答
1

这是该界面的 livedocs 参考。这几乎是显而易见的。

去引用:

通常,用户定义的类获得事件分派功能的最简单方法是扩展 EventDispatcher。

因此,

私有静态常量 emptyLink:EventDispatcher = {

于 2009-05-29T21:59:10.623 回答
0

我很久没有使用 Flex,这可能不符合您的要求,但为什么不使用 XML?我相信您可以将 TextInput 文本值设置为 XML 中的属性。

我正在使用伪代码,但这样的事情对我来说很有意义:

[Bindable] private static const currentLink:XML = <root>
                                                    <trigger1 value=""/>
                                                    <trigger2 value="" />
                                                  </root>;
...
<mx:TextInput id="trigger1" width ... text="{currentLink.trigger1.@value}" />

大概是这样的吧?

于 2009-05-29T21:45:25.440 回答