尝试在Flash AS3.0中使用BindingUtils

时间:2012-12-16 18:44:30

标签: actionscript-3 flex flex4

我无法在包含Flex SDK 4.0的AS3.0(Flash)中使此代码正常工作。

 import mx.binding.utils.*;


 [Bindable]
 var myValue:int = 0;
 var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");
 addEventListener( Event.ENTER_FRAME , ef);

 function ef(e:Event):void
 {
    trace("hello",getTimer());
    myValue = getTimer();
 }

 function myValueChanged(o:Object):void
 {
    trace("myValue: " + myValue.toString());
 }

我得到的输出是:

myValue: 0
hello 157
hello 168
hello 171
hello 177
....
....

等等。

但我希望正确的输出应该是:

myValue: 0
hello 157
myValue: 157
hello 168
myValue: 168
hello 171
myValue: 171
hello 177
myValue: 177
....
....

感谢。

4 个答案:

答案 0 :(得分:3)

数据绑定仅适用于Flex。

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx" enterFrame="ef(event)">

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import mx.binding.utils.*;

            [Bindable]
            public var myValue:int = 0;
            private var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");

            private function ef(e:Event):void
            {
                trace("hello", getTimer());
                myValue = getTimer();
            }

            private function myValueChanged(o:Object):void
            {
                trace("myValue: " + myValue.toString());
            }
        ]]>
    </fx:Script>
</s:WindowedApplication>

答案 1 :(得分:2)

我不确定Flash Pro编译器如何处理这些内容(我总是使用Flex SDK中的免费mxmlc编译器)。

这对你有用吗?

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.utils.getTimer;
  import mx.binding.utils.BindingUtils;

  public class BindingExample extends Sprite {

    private var model:Model;

    public function BindingExample()
    {
      model = new Model();
      BindingUtils.bindProperty(this, 'spy', model, ['value']);
      addEventListener( Event.ENTER_FRAME , onEnterFrame);
    }

    public function onEnterFrame(e:Event):void
    {
      model.value = getTimer();
    }

    public function set spy(value:int):void
    {
      trace('Bound property set to: ' + value);
    }
  }
}

class Model
{
  [Bindable]
  public var value:int;
}

如果没有,请尝试使用模型定义:

import flash.events.Event;
import flash.events.EventDispatcher;

class Model extends EventDispatcher
{
  private var _value:int;

  [Bindable("valueChange")]
  public function get value():int
  {
    return _value;
  }

  public function set value(value:int):void
  {
    if (_value != value)
    {
      trace('Model property set to: ' + value);
      _value = value;
      dispatchEvent(new Event("valueChange"));
    }
  }
}

如果这不起作用,请尝试使用模型:

import flash.events.EventDispatcher;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;

class Model extends EventDispatcher
{
  private var _value:int;

  [Bindable("propertyChange")]
  public function get value():int
  {
    return _value;
  }

  public function set value(value:int):void
  {
    if (_value != value)
    {
      trace('Model property set to: ' + value);
      var oldValue:int = _value;
      _value = value;
      dispatchEvent(new PropertyChangeEvent(
        PropertyChangeEvent.PROPERTY_CHANGE, false, false,
        PropertyChangeEventKind.UPDATE, "value", oldValue, value, this));
    }
  }
}

或者,也许使用ObjectProxy:

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.utils.getTimer;
  import mx.binding.utils.BindingUtils;
  import mx.utils.ObjectProxy;

  public class BindingExample extends Sprite {

    private var model:ObjectProxy;

    public function BindingExample()
    {
      model = new ObjectProxy({value: 0});
      BindingUtils.bindProperty(this, 'spy', model, ['value']);
      addEventListener( Event.ENTER_FRAME , onEnterFrame);
    }

    public function onEnterFrame(e:Event):void
    {
      model.value = getTimer();
    }

    public function set spy(value:int):void
    {
      trace('Bound property set to: ' + value);
    }
  }
}

使用mxmlc进行编译时,以上所有工作都很正常。我会避免使用ObjectProxy,因为它是最不安全的类型。

答案 2 :(得分:1)

您写道:

  

我无法在包含Flex SDK 4.0的AS3.0(Flash)中使此代码正常工作。

我认为这意味着您已经在使用mxmlc编译器,这对于Bindable元标记是必需的。

据我了解,将Bindable元标记添加到变量是一种监听PropertyChangeEvent的调度的方法:

Flex 4.6 API docs州:

  

[在变量上使用Bindable时] Flex编译器会自动为属性生成名为propertyChange的事件,类型为PropertyChangeEvent。

基本上是一种更简单的方法myValue.addEventListener(...)

因此,我们想要成为Bindable的变量必须是扩展EventDispatcher或实现IEventDispatcher的类型。原始int不是这种情况,它是您尝试使其成为可绑定的变量的类型。 <{1}}上的Bindable无效。

要使其工作,您可以将int变量包装在实现int的自定义类BindableInteger中。另一个选项是使用ObjectProxy,它允许您添加EventListeners并使对象可绑定,即使它不扩展IEventDispatcher或实现EventDispatcher

另外,请注意,您需要将变量设置为public,protected或private才能使Bindable正常工作。

Using the Bindable meta tag上的Flex 4.6文档:

  

您可以使用[Bindable]元数据标签(...)[b]在定义为变量的公共属性,受保护属性或私有属性之前使该特定属性支持绑定。

这不起作用:

IEventDispatcher

但这会:

[Bindable] var myValue:int = 0;

答案 3 :(得分:0)

绑定适用于类属性,不适用于局部变量,因此您需要创建类:

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;

import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;

public class astest extends Sprite
{

    [Bindable]
    public var myValue:int = 0;

    public function astest()
    {
        var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");
        addEventListener( Event.ENTER_FRAME , ef);
    }

    protected function ef(e:Event):void
    {
        trace("hello",getTimer());
        myValue = getTimer();
    }

    protected function myValueChanged(o:Object):void
    {
        trace("myValue: " + myValue.toString());
    }
}
}