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)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Blazor 将输入文本动态绑定到类/对象属性

标签上的绑定循环警告

socket_bind():无法绑定地址 [99](Amazon EC2 上的 Ubuntu)

vue中数据双向绑定的实现原理

如何在 Flex 3 中禁用已弃用的警告?

将标签绑定到类的属性