Flex警告:无法绑定到类'Object'上的属性'foo'(类不是IEventDispatcher)

时间:2009-05-29 20:50:24

标签: flex actionscript-3 binding flex3 mxml

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

我的容器对象的定义:

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)   警告:无法绑定到类'Object'上的属性'trigger5'(类不是IEventDispatcher)

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

显而易见的答案是我的对象需要是实现IEventDispatcher的类的实例。答案没有告诉我的是实现该界面的细节(需要什么?什么不是?),如果有一种更简单的方法可以做到这一点 - 就像一个内置的类,很乐意接受我的自定义属性并允许对于绑定,我不必担心实现界面的细节。

这样的课程存在吗?如果没有,完成这项任务的最低和/或公认标准是什么?

7 个答案:

答案 0 :(得分:15)

您需要使用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>

答案 1 :(得分:8)

Object不会发送事件。虽然您已经创建了变量Bindable,但是变量currentLink引用的对象的属性不能被绑定。

改为使用ObjectProxy

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

答案 2 :(得分:4)

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

  1. 使用mx:Binding标记将TextInput.text指向对象
  2. 使用BindingUtils以编程方式执行此操作。
  3. 在Flex 4中,他们引入了双向绑定@ {some.binding.expression}的新语法,但它在Flex 3中不可用。

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

    另一种选择是将原型包装在ObjectProxy中,作为其他SO成员建议的。

答案 3 :(得分:3)

关于如何在更大的项目中找出有问题的代码的提示 - 在两个上放一个断点

trace("warning: unable to bind to property '"
SDK的PropertyWatcher类中的

行(导航&gt;打开类型&gt; ...)。然后,Stacktrace将帮助您找到包含损坏绑定的ui组件。

答案 4 :(得分:2)

一般来说,你之所以“无法绑定到类上的属性foo,是因为你要么缺少foo的getter或setter 。你可以也使foo作用于一个公共变量,(虽然这打破了封装)

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

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

public function get foo() : FooObject {
...
}

答案 5 :(得分:1)

Here's the livedocs reference用于界面。这几乎是显而易见的。

引用:

  

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

因此,

  

private static const emptyLink:EventDispatcher = {

答案 6 :(得分: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}" />

也许是这样的事情?