`

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接口是不符的.

分享到:
评论

相关推荐

    Flex itemRenderer的详细教程

    `&lt;mx:Image&gt;` 和 `&lt;mx:VBox&gt;` 控件分别显示书籍的封面图片和标题作者信息。 #### 三、使用 MXML 和 ActionScript 定义 ItemRenderer 当需要更复杂的逻辑或交互时,仅依靠 MXML 来定义 ItemRenderer 可能不够。这时...

    FLEX动态树 动态图表

    &lt;fx:Script&gt; &lt;![CDATA[ [Bindable] [Embed("../png/internet.png")] // 自定义图标路径 private var myFolderClosedIcon:Class; [Bindable] [Embed("../png/phone.png")] private var myFolderOpenIcon:...

    Flex4特效源码

    &lt;fx:Effect id="fadeIn" type="Fade"&gt; &lt;mx:duration&gt;1000&lt;/mx:duration&gt; &lt;/fx:Effect&gt; &lt;fx:EffectTarget targets="{myComponent}"/&gt; ``` 这段代码定义了一个名为`fadeIn`的淡入效果,持续时间为1秒,并将其应用到...

    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:事件的流转控制.doc

    &lt;fx:Script&gt; &lt;![CDATA[ private function initApp():void { button.addEventListener(MouseEvent.CLICK, buttonClickHandler, true); // 捕获阶段监听 mypanel.addEventListener(MouseEvent.CLICK, ...

    Flex4.5之DataGrid表格组件的运用.pdf

    &lt;fx:Object dataField1="示例数据" dataField2="示例数据" dataField3="示例数据"/&gt; &lt;/s:typicalItem&gt; &lt;s:ArrayList&gt; &lt;fx:Object dataField1="数据1" dataField2="数据1" dataField3="数据1"/&gt; &lt;fx:Object data...

    Flex chart line 线性表(单线和双线)

    在Flex项目中,添加以下代码到你的MXML文件的`&lt;fx:Declarations&gt;`部分: ```xml &lt;fx:Script&gt; &lt;![CDATA[ import mx.collections.ArrayCollection; import mx.charts.LineChart; import mx.charts.series....

    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 + geoserver + openScales 平台搭建.pdf

    &lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:flex="main.flex.*"&gt; &lt;mx:Canvas&gt; &lt;os:Map&gt; &lt;os:MaxExtent/&gt; &lt;os:WMS name="Germany" url=...

    flex-menu.rar_Flex 4_Menu_flex_flex Menu_flex 菜单

    &lt;fx:Declarations&gt; &lt;s:MenuBar id="mainMenu"&gt; &lt;s:menuItems&gt; &lt;s:MenuItem label="File"&gt; &lt;s:menu&gt; &lt;s:Menu&gt; &lt;s:MenuItem label="Open"/&gt; &lt;s:MenuItem label="Save"/&gt; &lt;/s:Menu&gt; &lt;/s:menu&gt; &lt;/s:MenuItem&gt; ...

    Flex与JSON及XML的互操作

    &lt;compa&gt;&lt;jsp:expression&gt;compa&lt;/jsp:expression&gt;&lt;/compa&gt; &lt;compb&gt;&lt;jsp:expression&gt;compb&lt;/jsp:expression&gt;&lt;/compb&gt; &lt;/day&gt; &lt;jsp:scriptlet&gt; &lt;![CDATA[ } ]]&gt; &lt;/jsp:scriptlet&gt; &lt;/days&gt; &lt;/jsp:root&gt; ``` ...

    《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; ...

    构造flex3.5的带复选框的树(CheckBoxTree)

    &lt;fx:Component id="checkboxRenderer"&gt; &lt;mx:HBox width="100%"&gt; &lt;mx:CheckBox id="checkBox" label="{data.@label}"/&gt; &lt;mx:Label text="{data.@label}" verticalAlign="middle"/&gt; &lt;/mx:HBox&gt; &lt;/fx:Component&gt; ``...

    FLEX4的皮肤制作教程

    &lt;/fx:Metadata&gt; &lt;s:Ellipse width="100%" height="100%"&gt; &lt;s:fill&gt; &lt;s:SolidColor color="0x131313" color.over="#191919" color.down="#ffffff"/&gt; &lt;/s:fill&gt; &lt;s:stroke&gt; &lt;s:SolidColorStroke color="0x0c0d0...

    Flex内联itemRenderer

    &lt;fx:Component&gt; &lt;s:IconItemRenderer iconFunction="getIcon"&gt; &lt;s:Label text="{data.label}" /&gt; &lt;/s:IconItemRenderer&gt; &lt;/fx:Component&gt; &lt;/mx:itemRenderer&gt; &lt;/mx:List&gt; &lt;/mx:Application&gt; ``` 在这个例子...

    FLEX4 皮肤制作教程

    - **元数据**:`&lt;fx:Metadata&gt;`中的`[HostComponent]`属性指定了该皮肤对应的Flex控件,这里是`spark.components.Button`。 - **UI元素布局**: - 使用`&lt;s:Ellipse&gt;`绘制圆形背景,并通过`&lt;s:fill&gt;`和`&lt;s:stroke&gt;...

    FLEX _HTTPService的调用方法

    &lt;description&gt;Easy to use&lt;/description&gt; &lt;/product&gt; &lt;product productId="2"&gt; &lt;name&gt;Nokia6020&lt;/name&gt; &lt;description&gt;Easy to use&lt;/description&gt; &lt;/product&gt; &lt;product productId="3"&gt; &lt;name&gt;Nokia6030&lt;/name...

    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:...

Global site tag (gtag.js) - Google Analytics