我注意到 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 的两列的值都发生了变化,尽管 DataGrid 的第二列链接到 MyDummy 对象的同一个只读属性 MyPropertyFormatted。我发现这与我之前描述的行为不一致。
我的观点是:
1. 一方面,因为我将控件绑定到某个对象的单个实例,绑定不会在他的只读属性上触发。
2. 另一方面,当我在相同特定对象的集合上绑定控件时,绑定将在每个属性上触发(只读或非只读)。
如果我想在第 1 点的只读属性上触发绑定,我必须调度一个事件并精确到只读属性的 MetaTag,它们的绑定将根据此事件触发(如模型类代码中的注释所示.MyDummy 类)。
为什么这种行为不同?我想准确了解 ArrayCollection 实例的绑定做了什么,而单个实例的绑定没有。
感谢您的帮助。