Flex 警告:无法绑定到类“Object”上的属性“foo”(类不是 IEventDispatcher)
Posted
技术标签:
【中文标题】Flex 警告:无法绑定到类“Object”上的属性“foo”(类不是 IEventDispatcher)【英文标题】:Flex Warning: Unable to bind to property 'foo' on class 'Object' (class is not an IEventDispatcher) 【发布时间】:2010-10-30 00:13:41 【问题描述】:我有一个对象,其中包含十几个要绑定到表单元素的字段,以便我可以使用该对象将数据发送回服务器进行保存。
我的容器对象的定义:
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" >
<mx:VBox id="tpBoxes" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
<mx:TextInput id="trigger1" textAlign="left" text="currentLink.trigger1" />
<mx:TextInput id="trigger2" textAlign="left" text="currentLink.trigger2" />
<mx:TextInput id="trigger3" textAlign="left" text="currentLink.trigger3" />
<mx:TextInput id="trigger4" textAlign="left" text="currentLink.trigger4" />
<mx:TextInput id="trigger5" textAlign="left" text="currentLink.trigger5" />
</mx:VBox>
</mx:Panel>
当然,这编译和显示都很好,但是每个实例都有运行时警告:
警告:无法绑定到类“Object”上的属性“trigger1”(类不是 IEventDispatcher) 警告:无法绑定到类“Object”上的属性“trigger2”(类不是 IEventDispatcher) 警告:无法绑定到类“Object”上的属性“trigger3”(类不是 IEventDispatcher) 警告:无法绑定到类“Object”上的属性“trigger4”(类不是 IEventDispatcher) 警告:无法绑定到类“Object”上的属性“trigger5”(类不是 IEventDispatcher)
当TextInput
字段发生变化时,currentLink
对象不会更新。
显而易见的答案是我的对象需要是实现IEventDispatcher
的类的实例。该答案没有告诉我的是实现该接口的细节(需要什么?什么不是?),以及是否有更简单的方法来做到这一点——比如一个内置类,它很乐意接受我的自定义属性并允许用于绑定,我不必担心实现接口的细节。
这样的类存在吗?如果不是,那么完成这项任务的最低限度和/或公认标准是什么?
【问题讨论】:
【参考方案1】:您需要使用 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" >
<mx:VBox id="tpBoxes" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
<mx:TextInput id="trigger1" textAlign="left" text="currentLink.trigger1" valueCommit="currentLink.trigger1 = trigger1.text;"/>
<mx:Button label="Click" click="handleClick()"/>
</mx:VBox>
</mx:Panel>
</mx:WindowedApplication>
【讨论】:
【参考方案2】:Object
不分派事件。虽然你已经将变量设为Bindable,但是变量currentLink
所引用的对象的属性是无法绑定的。
请改用ObjectProxy
。
[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);
【讨论】:
【参考方案3】:您首先要知道的是,Flex 3 中的绑定不是双向的。绑定表达式将确保如果绑定表达式的源 (currentLink.trigger1) 发生更改,则目标 (TextInput) 将收到更改通知并相应地更新。如果您希望绑定向另一个方向发展,至少有两种方法可以做到这一点:
-
使用 mx:Binding 标签将 TextInput.text 引导回对象
改用 BindingUtils 以编程方式执行此操作。
在 Flex 4 中,他们引入了一种用于双向绑定 @some.binding.expression 的新语法,但在 Flex 3 中不可用。
第二部分:您收到的错误是因为您绑定到“通用”原型对象。当您将 [Bindable] 元数据标记应用于属性或类时,MXMLC 编译器会生成 AS 代码,其中包括使用绑定实用程序和属性更改观察程序来进行绑定。但是,您不能让原型对象执行此操作,因为它是内置的。您可以创建一个可绑定的自定义 ActionScript 类(或具有可绑定的某些属性)。 MXMLC 编译器将生成一个实现 IEventDispatcher 并因此支持绑定的类。这具有比原型对象更快的优点,并且还提供编译时检查,即如果您引用无效属性,您将收到编译器错误。
另一种选择是按照其他 SO 成员的建议将原型包装在 ObjectProxy 中。
【讨论】:
如果我能接受 2 个答案,这个答案将是 #2。我选择了 Gabriel's,因为它是我想做的最简单的解决方案。不过,感谢您提供所有信息!【参考方案4】:关于如何在大型项目中找出有问题的代码的提示 - 在两者上设置断点
trace("warning: unable to bind to property '"
SDK 的 PropertyWatcher 类中的行(Navigate > Open Type > ...)。 Stacktrace 然后将帮助您找到保存损坏绑定的 ui 组件。
【讨论】:
【参考方案5】:一般来说,您“无法绑定到类上的属性 foo”的原因是您缺少 foo 的 getter 或 setter。您可以 还将 foo 限定为公共变量,(尽管这会破坏封装)
所以你需要这两个来让它消失:
public function set foo (o:FooObject) : void
...
或
public function get foo() : FooObject
...
【讨论】:
【参考方案6】:Here's the livedocs reference 用于接口。这几乎是显而易见的。
引用:
一般来说,用户定义的类获得事件分派功能的最简单方法是扩展 EventDispatcher。
因此,
私有静态常量 emptyLink:EventDispatcher =
【讨论】:
您的链接没有转到您认为的 livedocs 中的页面。每个 livedocs 参考页面的页脚都有一个“当前链接:...”,其中包含用于直接链接您正在查看的页面的 URL。用那个。 :)【参考方案7】:我很久没有使用 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" />
大概是这样的吧?
【讨论】:
以上是关于Flex 警告:无法绑定到类“Object”上的属性“foo”(类不是 IEventDispatcher)的主要内容,如果未能解决你的问题,请参考以下文章