【问题标题】:Flex Warning: Unable to bind to property 'foo' on class 'Object' (class is not an IEventDispatcher)Flex 警告:无法绑定到类“Object”上的属性“foo”(类不是 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" 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 的类的实例。该答案没有告诉我的是实现该接口的细节(需要什么?什么不是?),以及是否有更简单的方法来做到这一点——比如一个内置类,它很乐意接受我的自定义属性并允许用于绑定,我不必担心实现接口的细节。

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

【问题讨论】:

    标签: apache-flex actionscript-3 binding flex3 mxml


    【解决方案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" 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>
    

    【讨论】:

      【解决方案2】:

      Object 不分派事件。虽然你已经将变量设为Bindable,但是变量currentLink所引用的对象的属性是无法绑定的。

      请改用ObjectProxy

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

      【讨论】:

        【解决方案3】:

        您首先要知道的是,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 中。

        【讨论】:

        • 如果我能接受 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}" />
            

            大概是这样的吧?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-09-01
              相关资源
              最近更新 更多