Flex のバインディングで予期しない動作が発生することに気付きました。私のコードは次のとおりです。
アプリケーションコード
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" xmlns:Model="Model.*">
<mx:Script>
<![CDATA[
import Model.DataDummy;
]]>
</mx:Script>
<mx:HBox width="100%" horizontalGap="30">
<mx:Button id="buttonChange1" label="Change property value" click="myDummy._resetMyProperty();" />
<mx:Label id="labelRaw" text="{'My Property=' + myDummy.MyProperty}" opaqueBackground="#DDDDDD" />
<mx:Label id="labelFormatted" text="{'My Property formatted=' + myDummy.MyPropertyFormatted}" opaqueBackground="#DDDDDD" />
</mx:HBox>
<Model:MyDummy id="myDummy" />
<mx:DataGrid id="dataGrid"
width="100%" dataProvider="{DataDummy.Dummies}">
<mx:columns>
<mx:DataGridColumn dataField="MyProperty" headerText="My property" />
<mx:DataGridColumn dataField="MyPropertyFormatted" headerText="My property Formatted" />
</mx:columns>
</mx:DataGrid>
<mx:Button id="buttonChange2" click="{for each ( var d:MyDummy in DataDummy.Dummies ){d._resetMyProperty();}}" label="Change property value in DataGrid" />
</mx:Application>
Model.MyDummy クラス コード
package Model
{
import flash.events.EventDispatcher;
import mx.formatters.NumberFormatter;
import mx.utils.StringUtil;
[Bindable]
public class MyDummy extends EventDispatcher
{
/*** Constructor ***/
public function MyDummy()
{
this._resetMyProperty();
}
/*** Properties ***/
private var _myProperty:Number;
public function get MyProperty():Number
{
return _myProperty;
}
public function set MyProperty(value:Number):void
{
if ( value !== _myProperty )
{
_myProperty = value;
//var event:Event = new Event("ID_Changed");
//this.dispatchEvent(event);
}
}
//[Bindable (event="ID_Changed", type="flash.events.Event")]
public function get MyPropertyFormatted():String
{
var idFormatted:String = "";
if ( ! isNaN(this.MyProperty) )
{
var formatter:NumberFormatter = new NumberFormatter();
formatter.precision = 2;
idFormatted = formatter.format(this.MyProperty);
}
else
idFormatted = MyProperty.toString();
return StringUtil.substitute( "{0} (My property has been formatted)", idFormatted );
}
/*** Methods ***/
public function _resetMyProperty():void
{
this.MyProperty = Math.round(Math.random() * 1000000000);
}
}
}
Model.DataDummy クラス コード
package Model
{
import mx.collections.ArrayCollection;
public class DataDummy
{
private static var _dummies:ArrayCollection;
public static function get Dummies():ArrayCollection
{
if ( _dummies == null )
{
_dummies = new ArrayCollection();
_dummies.addItem(new MyDummy());
_dummies.addItem(new MyDummy());
}
return _dummies;
}
}
}
動作は次のとおりです。
- buttonChange1 をクリックすると、インスタンス myDummy で _resetMyProperty が呼び出されます。
その結果、ラベル「labelRaw」のテキストは変更され、ラベル「labelFormatted」のテキストは変更されません。これは、Flex のドキュメントによると、MyPropertyFormatted が読み取り専用プロパティであり、その読み取り専用プロパティがアプリケーションの初期化時にのみバインドされ、その後ではバインドされないために発生します。これで、私は同意します。 - buttonChange2 をクリックすると、ArrayCollection Model.DataDummy.Dummies のすべての MyDummy 要素で resetMyProperty メソッドが呼び出されます (この静的プロパティは DataGrid にバインドされます)。
その結果、DataGrid の 2 番目の列が MyDummy オブジェクトの同じ読み取り専用プロパティ MyPropertyFormatted にリンクされているにもかかわらず、DataGrid の両方の列の値が変更されます。これは、私が説明した以前の動作と矛盾していると思います。
私のポイントは次のとおり
です。 1. 一方では、コントロールを特定のオブジェクトの単一のインスタンスにバインドしているため、バインドは彼の読み取り専用プロパティでトリガーされません。
2.一方、同じ特定のオブジェクトのコレクションにコントロールをバインドすると、すべてのプロパティ (読み取り専用かどうかに関係なく) でバインドがトリガーされます。
ポイント1の読み取り専用プロパティでバインディングをトリガーする場合は、イベントをディスパッチし、読み取り専用プロパティのMetaTagで、このイベントに従ってバインディングがトリガーされることを正確にする必要があります(クラスModelのコードのコメントを示すように) .MyDummy クラス)。
この動作が異なるのはなぜですか? ArrayCollection インスタンスのバインディングが何を行い、単一のインスタンスのバインディングが何を行わないかを正確に理解したいと思います。
ご協力ありがとうございました。