`

FLEX : ObjectProxy & <fx:Model> tag

    博客分类:
  • FLEX
阅读更多
今天碰到了一个非常让我困扰的问题,使我觉得很有必要对Object的可绑定代理对象ObjectProxy做一个单独的说明;而<fx:Model>,在编译时正是会被编译为ObjectProxy类型(The most common type of MXML-based model is the <fx:Model> tag, which is compiled into an ActionScript object of type mx.utils.ObjectProxy, which contains a tree of objects when your data is in a hierarchy, with no type information. The leaves of the Object tree are scalar values)。

关于数据绑定的帖子导航:
http://wuaner.iteye.com/blog/1056650
关于 warning: unable to bind to property 'cntCt' on class 'Object' (class is not an IEventDispatcher) 导航:
http://wuaner.iteye.com/blog/1054153


问题描述:
两个级联弹出的模态窗口TitleWindow;一级窗口中有名为counterDg的datagrid,其dataProvider为名为counterAC的arrayCollection。二级窗口对一级窗口中的counterDg中数据做增删改(实际就是对counterDg的dataProvider counterAC做增删改;这里的增删改,并不会提交后台,在一级窗口被提交后才会做提交后台的动作)。最开始时,counterAC中存的是Object
问题就出在二级窗口中对一级窗口counterDg做修改的时候
改的时候是需要将数据带到二级窗口的,自然一级窗口counterDg.selectedItem会有向二级窗口输入域的单向绑定(这里不应该用双向绑定,因为双向绑定的话,在二级窗口中对绑定的数据做修改,会立即触发一级窗口dataGrid中当前选定行随之而改变,即使你连“提交”按钮都没点;这显然是不合逻辑的。),如:
<!-- 切记这里不适合配双向绑定  @{counter.cntOt}  -->
<mx:FormItem label="开放时间:">
	<myDateTime:DateTimeSelectorFinal id="cntOt" selectedDate="{counter.cntOt}"/> 
</mx:FormItem>
因为counterAC中放的是Object,二级窗口中自然也用一个Object接一级窗口dataGrid的选定项:
[Bindable]
public var counter:Object;

在二级窗口点击提交按钮的方法中,集中做反向的绑定工作:使用BindingUtils动态的将页面输入域的值绑定回counter:
if(null != counter) {  //修改
					BindingUtils.bindProperty(counter, "cnt", cnt, ["selectedItem","data"]);
					BindingUtils.bindProperty(counter, "cntCls", cntCls, ["selectedItem","data"]);
					BindingUtils.bindProperty(counter, "cntOt", cntOt, "selectedDate");
					BindingUtils.bindProperty(counter, "cntCt", cntCt, "selectedDate");
					BindingUtils.bindProperty(counter, "cntPot", cntPot, "selectedDate");
					BindingUtils.bindProperty(counter, "cntPct", cntPct, "selectedDate");
					PopUpManager.removePopUp(this);
} else { //增加
					//add item into counterDg's dataProvider : counterAC
					this.dispatchEvent(new Event("addCounter")); 
}
因为counter为Object类型,自然这个警告及时出现了:
warning: unable to bind to property 'cntCt' on class 'Object' (class is not an IEventDispatcher)
这时候让我费解的情况发生了:尽管有上面的警告,但通过debug跟踪,发现二级页面的输入域的值还是被成功绑定到了一级TitleWindow的counterAC,counterAC的值已经变成了变化后的值;但怪就怪在:使用counterAC作为dataProvider的counterDg没有随着二级TitleWindow的关闭而自动刷新!但通过滚动counterDg的滚动条,使更新的数据行在可见区域中不可见,再滚回来后,你会发现counterDg中刚才错误的数据行变成正确的了!
明明警告我说“不能绑定Object的属性xxx”,却还绑定成功了;刚要以为这个警告无关紧要,却发现绑定仅仅对counterAC起了作用,可是却不会刷新使用counterAC作为dataProvider的counterDg,这算什么个事啊。。。
既然有这样的问题存在,那就从警告入手,着手解决。通过将counterAC中放ObjectProxy对象而不是放Object对象,来解决掉这个警告:
//counterAC初始化的改动:
var counter1:Object = new Object();
counter1.xxx = "yyy";
...
counterAC.addItem(new ObjectProxy(counter1)); //由原来的直接放Object,改为放ObjectProxy

//二级页面中接受一级页面dataGrid当前选定行的变量counter也改为ObjectProxy类型:
[Bindable]
public var counter:ObjectProxy; 

//一级页面修改函数在为二级页面counter赋值时也赋ObjectProxy:
protected function editFidsDepfCounterHandler(event:MouseEvent):void
			{
				//DateGrid的selectedItem返回的是Object类型
				var selectedItem:Object = counterDg.selectedItem;
				if(null == selectedItem) {
					Alert.show("请选择要修改的记录!");
				} else {
					var win : AddFidsDepfCounterWindow = new AddFidsDepfCounterWindow();
					win.counter = new ObjectProxy(selectedItem);
					win.title="修改";
					PopUpManager.addPopUp(win,this,true);
					PopUpManager.centerPopUp(win);
				}
			}


增加时,通过addItem加到一级页面counterAC中的也应该是ObjectProxy:
引用
//二级页面中:
<fx:Declarations>
		<!-- <fx:Model> tag  is compiled into an ActionScript object of type mx.utils.ObjectProxy -->
		<fx:Model id="addCounterInfo">
			<counter>
				<cnt>{cnt.selectedItem.data}</cnt>
				<cntCls>{cntCls.selectedItem.data}</cntCls>
				<cntOt>{cntOt.selectedDate}</cntOt>
				<cntCt>{cntCt.selectedDate}</cntCt>
				<cntPot>{cntPot.selectedDate}</cntPot>
				<cntPct>{cntPct.selectedDate}</cntPct>
			</counter>
		</fx:Model>
	</fx:Declarations>
//一级页面中:
protected function addFidsDepfCounterHandler(event:MouseEvent):void
{
				var win : AddFidsDepfCounterWindow = new AddFidsDepfCounterWindow();
				win.title="增加";
				win.addEventListener("addCounter", saveNewCounter); 
				PopUpManager.addPopUp(win,this,true);
				PopUpManager.centerPopUp(win);
}
protected function saveNewCounter(event:Event):void
{
				//trace(event);
				var win:AddFidsDepfCounterWindow = event.target as AddFidsDepfCounterWindow;
				counterAC.addItem(win.addCounterInfo); //因为addCounterInfo是通过<fx:Model>定义的,所以它本省就是个ObjectProxy类型的对象
				PopUpManager.removePopUp(win);
}


至此,问题解决,一级页面dataGrid在二级页面点击确定后被成功刷新,也没有了刚才的警告。
明白了一个道理:flex中的warning不比error影响力小!千万不能置之不理!




关于ObjectProxy:
Using Flex 4.5 / Using data-driven UI components / Storing data 
  -> Defining a data model:
     http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7b51.html#WS2db454920e96a9e51e63e3d11c0bf66ba1-7ffb

引用
The most common type of MXML-based model is the <fx:Model> tag, which is compiled into an ActionScript object of type mx.utils.ObjectProxy, which contains a tree of objects when your data is in a hierarchy, with no type information. The leaves of the Object tree are scalar values. Because models that are defined in <fx:Model> tags contain no type information or business logic, you should use them only for the simplest cases. Define models in ActionScript classes when you need the typed properties or you want to add business logic.

  -> Using a data model as a value object:
     http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf66ba1-7ff7.html



under the hood flex data model using the fx:model and fx:xml tags:
http://elromdesign.com/blog/2009/07/20/under-the-hood-flex-data-model-using-the-fxmodel-and-fxxml-tags/





通过remoteObject调用后台得到的result也可能本身就是ObjectProxy类型的,只要:
http://tech.groups.yahoo.com/group/flexcoders/message/66621
引用
You'll have to determine why an ObjectProxy is being created... typically it's because an anonymous Object was returned and RemoteObject had makeObjectsBindable="true" (which it is by default).
我的返回结果为ObjectProxy的例子:
引用
java后台,返回类型是Map:
public Map<FidsDevice, List<FidsChannelRefDev>> findDevAndChannelByDevId(String devId) {
		return this.iFidsDeviceService.findDevAndChannelByDevId(devId);
	}
flex前台,makeObjectsBindable="true":
<mx:RemoteObject id="iFidsDeviceFlexService" destination="iFidsDeviceFlexService" makeObjectsBindable="true"> 
			<mx:method name="findDevAndChannelByDevId" result="devAndChannelDataHandler(event)" >
				<mx:arguments>
					<id>{updatedDevId}</id>
				</mx:arguments>
			</mx:method>
		</mx:RemoteObject>







使用ObjectProxy时有个注意事项:
http://www.smithfox.com/?e=96
引用
只能处理当前所代理类的直接属性, 不能感知nested field property变化, 这明显和它声明实现IPropertyChangeNotifier接口是不符的.

分享到:
评论

相关推荐

    Adobe Flex Builder 3.0官方使用教程

    &lt;br&gt; Contents:&lt;br&gt;&lt;br&gt;Chapter 1: Learning Flex Builder&lt;br&gt;Chapter 2: About Flex Builder&lt;br&gt;Chapter 3: Flex Builder Workbench Basics&lt;br&gt;Chapter 4: Working with Projects&lt;br&gt;Chapter 5: Navigating and ...

    Flash Sample

    &lt;br&gt;Audio: Sound completion event&lt;br&gt;Create your own music mix with this audio mixer.&lt;br&gt; &lt;br&gt;Audio: Load sounds&lt;br&gt;Control the playback of three different MP3 files.&lt;br&gt; &lt;br&gt;Feature highlight: Load ...

    flex柱状图动态切换数据源实例

    该flex应用程序演示了柱状图动态切换数据源 &lt;mx:ColumnChart x="6" y="65" id="columnchart1" showDataTips="true" dataProvider="{list}" height="390" itemClick="onItemClick(event)"&gt; &lt;mx:horizontalAxis&gt; ...

    Flex Olap完整项目源码,可直接运行

    &lt;mx:Script source="include/OLAPAppInFlex.as" /&gt; &lt;mx:Script source="include/Chart.as" /&gt; &lt;mx:Script source="include/FlexBIDataGrid.as" /&gt; &lt;mx:Script source="include/OLAPGridConfigure.as" /&gt; &lt;mx:Style ...

    flex4cookbook

    &lt;fx:Script&gt; &lt;![CDATA[ import mx.events.FlexEvent; protected var names:Array = ['Leif','Zach','Stacey','Seth','Leonard']; protected var titles:Array = ['Evangelist','Director', 'Information ...

    flex导出excel的代码

    &lt;mx:Script&gt; &lt;![CDATA[ import mx.controls.CheckBox; import mx.controls.Alert; import com.as3xls.xls.ExcelFile; import com.as3xls.xls.Sheet; import flash.filesystem.*; [Bindable] private ...

    《Flex第一步》书中源代码1

    &lt;name&gt;com.adobe.flexbuilder.project.flexbuilder&lt;/name&gt; &lt;arguments&gt; &lt;/arguments&gt; &lt;/buildCommand&gt; &lt;/buildSpec&gt; &lt;natures&gt; &lt;nature&gt;com.adobe.flexbuilder.project.flexnature&lt;/nature&gt; ...

    flex fusionchart 破解

    &lt;fx:Declarations&gt; &lt;!-- 将非可视元素(例如服务、值对象)放在此处 --&gt; &lt;/fx:Declarations&gt; &lt;ns1:FusionCharts id="fc" width="100%" height="100%" FCChartType="Column3D"&gt; &lt;/ns1:FusionCharts&gt; &lt;fx:...

    flex与java通信,通过插件blazed

    --flex与webservice交互这里调用一个天气预报的webservice--&gt; &lt;s:WebService id="ws" wsdl="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl" fault="ws_faultHandler(event)" result="ws_...

    flex 初学者入门资料

    快步进入flex门槛 1.效果-模糊化 &lt;mx:Blur id="numbersBlur" target="{myLabel}" blurYFrom="10.0" blurYTo="0.0" blurXFrom="10.0" blurXTo="0.0" duration="2000"/&gt; 2.效果-滤镜 &lt;mx:Glow id="buttonGlow" color...

    Flash(ActionScript 3.0) Tree组织结构树

    &lt;fx:Declarations&gt; &lt;!-- 将非可视元素(例如服务、值对象)放在此处 --&gt; &lt;fx:XML source="assets/relation.xml" id="data"/&gt; &lt;/fx:Declarations&gt; &lt;component:UserTree id="treeStruct" x="0" y="0" width="277...

    <flex第一步>光盘源文件1

    &lt;flex第一步&gt;光盘源文件1

    Flex4入门经典<Hello!Flex4>附带源码

    终于出来flex4的新教程了,200多页,简单明了,入门经典!正向作者所说:使用flex4开发程序就应当向使用它一样的简单....;压缩包里面配有源代码,可以方便查看;

    flexjava交互

    &lt;source&gt;bean.MoginDemo &lt;/source&gt; &lt;scope&gt;application&lt;/scope&gt; &lt;/properties&gt; &lt;/destination&gt; 3. java package bean; import java.util.*; public class LoginDemo { public String validateLogin(String ...

    flex实列demo

    &lt;mx:Panel width="100%" height="100%" title="Content" marginTop="1" marginBottom="1" marginLeft="1" marginRight="1" &gt; &lt;IFrame id="iFrame" source=...

    FlashBuilder

    &lt;/fx:Script&gt; &lt;s:VGroup left="6" right="14" top="10" bottom="10" gestureSwipe="onSwipe(event)"&gt; &lt;s:Image source="assets/0 (3).jpg" id="image" width="472" height="423" horizontalAlign="center"/&gt; &lt;s...

    flex开发对时间控制

    flex 对时间的关注&lt;mx:Script&gt; &lt;![CDATA[ // Event handler for the DateField change event. private function dateChanged(date:Date):void { if (date == null) selection.text = "Date selected: "; ...

    AdobeAirAdobeAIRInstaller part2

    ActionScript &lt;br&gt; HTML / JavaScript / CSS / Ajax &lt;br&gt; PDF 可嵌入任何应用程序中 &lt;br&gt;作为结果,AIR 应用程序可以是:&lt;br&gt;&lt;br&gt; 基于Flash 或 Flex:应用程序根内容(理解为容器)为Flash/Flex (SWF) &lt;br&gt; 基于...

    flex事例

    &lt;br&gt;&lt;br&gt; &lt;br&gt;&lt;br&gt;Flex用MXML和ActionScript来编写。MXML最终编译成SWF文件。MXML就是在XML上写HTML 。MXML比HTML更结构化,提供了跟丰富的标签。&lt;br&gt;&lt;br&gt;ActionScript和JavaScript都是客户端语言。我对ActionScript...

    template:代码生成器(cpp flex bison lua)

    代码生成器 依赖项: * flex * 野牛 * liblua5.2-dev 句法 从名称来看 - 主要任务是生成代码(使用语言“模板”)。 var: 变量 const: 常数 &lt;var&gt; &lt;var&gt;subname]&gt; ...&lt;if&gt;TRUE&lt;else&gt;FALSE&lt;/if

Global site tag (gtag.js) - Google Analytics