我注意到,在Flex的結合意想不到的行爲,我的代碼如下: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 class code
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,_resetMyProperty被稱爲在實例myDummy。
結果是標籤「labelRaw」的文本已更改,標籤「labelFormatted」的文本未更改。這種情況的發生是因爲MyPropertyFormatted是一個只讀屬性,而且只讀屬性僅在應用程序初始化時綁定,而不是之後,根據Flex文檔。有了這個,我同意。 - 當我點擊buttonChange2,resetMyProperty方法稱爲ArrayCollection的Model.DataDummy.Dummies的每MyDummy元素(該靜態屬性綁定到DataGrid)。
結果是DataGrid的兩列都將其值更改爲,儘管DataGrid的第二列鏈接到MyDummy對象的相同只讀屬性MyPropertyFormatted。我發現這與我描述的以前的行爲不一致。
我的觀點是:
1.一方面,因爲我結合我的控制到某個對象的單個實例,結合不會對他的只讀屬性觸發。另一方面,當我綁定一個相同的特定對象的集合上的控件時,綁定將在每個屬性上觸發(只讀或不是)。
如果我想在點1的只讀屬性上觸發綁定,我必須調度一個事件,並精確地在只讀屬性的MetaTag上根據這個事件觸發它們的綁定(如代碼中的註釋Model.MyDummy類的類)。
爲什麼這種行爲有所不同?我想精確地理解一個ArrayCollection實例的綁定所做的事情,即單個實例的綁定不會。
謝謝你的幫助。
它能解決你的問題嗎? :) – Constantiner 2011-05-04 14:36:17
謝謝你的回答,並糾正我的命名約定(我必須失去這種壞習慣!)。它解決了這個問題,但我仍然不明白我提供的示例中ArrayCollection的行爲。我的意思是,由於readonly屬性不會觸發綁定,然後更新標籤的文本,爲什麼在更改MyProperty的值時更新了只讀屬性的DataGridColumn?是否ArrayCollection類強制綁定它包含的每個項目的所有公共屬性,即使是隻讀的項目? – x80 2011-05-04 14:40:53
對於你的情況,你有'[Bindable]'MyDummy'類的標籤,這意味着Flex爲所有公共變量和所有get-set對(例如代碼中的MyProperty)生成所有的'propertyChange'事件。這樣'ArrayCollection'監聽元素的變化,並用'event.kind =「update」'調度'collectionChangeEvent'。 'DataGrid'監聽這個事件並重繪其可見的原始數據。 – Constantiner 2011-05-04 14:51:25