Flex 警告:无法绑定到属性“foo” 在“对象”类上 (类不是 IEventDispatcher)
我有一个对象,其中包含十几个要绑定到表单元素的字段,以便我可以使用该对象将数据发送回服务器进行保存。
我的容器对象的定义:
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)
并且当 TextInput
字段更改时,currentLink
对象不会更新。
显而易见的答案是我的对象需要是实现 IEventDispatcher 的类的实例。 这个答案没有告诉我的是实现该接口的细节(需要什么?不需要什么?),以及是否有一种更简单的方法来做到这一点——比如一个内置的类,它将很乐意接受我的自定义属性并允许对于绑定,我不必担心实现接口的细节。
存在这样的类吗? 如果不是,完成这项任务的最低限度和/或可接受的标准是什么?
I've got an object that contains a dozen or so fields I want to bind to form elements, so that I can use that object to send the data back to the server to be saved.
Definition of my container object:
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
is assigned at runtime to a specific index from an ArrayCollection, I'm just using the emptyLink
object for initialization purposes, mostly.
<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>
Of course, this compiles and displays just fine, but there are runtime warnings for each instance:
warning: unable to bind to property 'trigger1' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'trigger2' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'trigger3' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'trigger4' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'trigger5' on class 'Object' (class is not an IEventDispatcher)
And the currentLink
object is not updated when the TextInput
fields are changed.
The obvious answer is that my object needs to be an instance of a class that implements IEventDispatcher
. What that answer doesn't tell me is the particulars of implementing that interface (what's required? what's not?), and if there is a simpler way to do this -- like a built in class that will gladly accept my custom properties and allow for binding, without me having to worry about the particulars of implementing the interface.
Does such a class exist? If not, what's the bare minimum and/or accepted standard for accomplishing this task?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您需要使用 ObjectProxy (正如 Chetan 提到的) - 但您还需要使用 valueCommit 将您在输入中输入的文本返回到您的对象中:
You need to use ObjectProxy (as Chetan mentions) - but you also need to use valueCommit to get the text you enter in the input BACK into your object:
Object
不调度事件。 尽管您已将变量设置为可绑定,但无法绑定变量currentLink
引用的对象的属性。请改用
ObjectProxy
。Object
doesn't dispatch events. Although you have made the variable Bindable, the properties of the object referenced by the variablecurrentLink
can not be bound.Use
ObjectProxy
instead.您需要了解的第一件事是 Flex 3 中的绑定不是双向的。 绑定表达式将确保如果绑定表达式的源 (currentLink.trigger1) 发生更改,则目标 (TextInput) 将收到更改通知并相应更新。 如果您希望绑定向另一个方向进行,至少有两种方法可以实现此目的:
在 Flex 4 中,他们引入了一种新的双向绑定语法 @{some.binding.expression} 但在 Flex 3 中不可用。
第二部分:您收到的错误是因为您正在绑定到“通用”原型对象。 当您将 [Bindable] 元数据标记应用于属性或类时,MXMLC 编译器会生成 AS 代码,其中包括使用绑定实用程序和属性更改观察程序来实现绑定。 但是,您不能让原型对象执行此操作,因为它是内置的。 您可以创建可绑定(或具有某些可绑定属性)的自定义 ActionScript 类。 MXMLC 编译器将生成一个实现 IEventDispatcher 的类,因此支持绑定。 这样做的优点是比原型对象更快,并且还可以进行编译时检查,即如果引用无效属性,您将收到编译器错误。
另一种选择是按照其他 SO 成员之一的建议将原型包装在 ObjectProxy 中。
The first thing you'll want to know is that binding in Flex 3 is not bidirectional. The binding expression will ensure that if the source of the binding expression (currentLink.trigger1) changes that the target (TextInput) will receive notification of the change and update accordingly. If you want the binding to go in the other direction, there are at least two ways to do this:
In Flex 4 they are introducing a new syntax for bidirectional binding @{some.binding.expression} but it's not available in Flex 3.
On the 2nd part: the error that you're receiving is because you are binding to a "generic" prototype Object. When you apply the [Bindable] metadata tag to a property or class, the MXMLC compiler generates AS code that includes use of binding utilities and property change watchers to do make the binding happen. However you can't make the prototype Object do this since it's a built-in. You can create a custom ActionScript class which is bindable (or has certain properties bindable). The MXMLC compiler will generate a class which implements IEventDispatcher and therefore supports binding. This has the advantage of being faster than prototype objects and also gives you compile-time checking, i.e. you will receive a compiler error if you reference an invalid property.
The other alternative is to wrap your prototype in ObjectProxy as one of the other SO members has suggested.
关于如何在较大项目中找出有问题的代码的提示 -
在 SDK 的 PropertyWatcher 类中的两行上放置一个断点(Navigate > Open Type > ...)。 然后 Stacktrace 将帮助您找到保存损坏绑定的 ui 组件。
Just a tip on how to find out the offending code in a larger project - put a breakpoint on the two
lines in the SDK's PropertyWatcher class (Navigate > Open Type > ...). Stacktrace will then help you find the ui component that holds the broken binding.
一般来说,您得到“无法绑定到类上的属性 foo 的原因是因为您缺少 foo 的 getter 或 setter。您也可以 foo 的作用域为公共变量,(尽管这破坏了封装)
所以你需要这两个来让它消失:
或者
In general, the reason why you get "unable to bind to property foo on a class, is because you are either missing a getter or setter for foo. You could also make foo scoped to a public variable, (although this breaks encapsulation)
So you need Both of these to make it go away:
or
这是该界面的 livedocs 参考。 这几乎是显而易见的。
去引用:
因此,
Here's the livedocs reference for the interface. It's pretty much what would be obvious.
To quote:
Hence,
我使用 Flex 的时间不长,这可能不符合您的要求,但为什么不使用 XML呢? 我相信您可以将 TextInput 文本值设置为 XML 中的属性。
我正在使用伪代码,但这样的东西对我来说很有意义:
也许是这样的东西?
I haven't been using Flex for very long, and this might not fit your requirements, but why not use XML? I believe you can set the TextInput text value to attributes in the XML.
I'm using pseudo-code, but something like this makes sense to me:
Something like this, perhaps?