2

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

4 に答える 4

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>
于 2012-12-23T13:55:12.900 に答える
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 は型安全性が最も低いため、避けたいと思います。

于 2012-12-27T20:09:47.840 に答える
1

あなたが書いた:

Flex SDK 4.0 が含まれている AS3.0 (Flash) でこのコードを動作させることができません。

これは、Bindable メタタグが機能するために必要な mxmlc コンパイラを既に使用していることを意味すると思います。

私が理解しているように、Bindable メタ タグを変数に追加することは、次のディスパッチをリッスンする方法ですPropertyChangeEvent

Flex 4.6 API ドキュメントには次のように記載されています。

[変数で Bindable を使用する場合] Flex コンパイラは、プロパティに対して、PropertyChangeEvent タイプの propertyChange という名前のイベントを自動的に生成します。

基本的にはもっと簡単な方法myValue.addEventListener(...)

したがって、Bindable にしたい変数は、拡張EventDispatcherまたは実装する型でなければなりませんIEventDispatcherintこれは、バインド可能にしようとしている変数の型であるプリミティブには当てはまりません。Bindableでは動作しintません。

それを機能させるには、変数を実装intするカスタム クラスでラップすることができます。もう 1 つのオプションは、ObjectProxyを使用することです。これにより、EventListeners を追加して、オブジェクトが拡張または実装されていなくてもオブジェクトをバインド可能にすることができます。BindableIntegerIEventDispatcherEventDispatcherIEventDispatcher

また、Bindable を機能させるには、変数を public、protected、または private にする必要があることに注意してください。

Bindable メタ タグの使用に関する Flex 4.6 ドキュメント:

[Bindable] メタデータ タグ (...) [b] を変数として定義されたパブリック、プロテクト、またはプライベート プロパティの前に使用して、その特定のプロパティがバインドをサポートするようにすることができます。

これは機能しません:

[Bindable] var myValue:int = 0;

しかし、これは:

[Bindable] public var myValue:int = o;
于 2012-12-23T14:30:34.997 に答える
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());
    }
}
}
于 2012-12-17T12:16:32.457 に答える