`

FLEX:Nested Object & Nested Data Grid

    博客分类:
  • FLEX
阅读更多
Flex Nested Object & Nested Data Grid:
http://natescodevault.com/2008/10/11/nested-data-grid/



在使用flex时,如果一个vo的属性是另一个vo,在datagrid中做数据展现时,可以使用 vo1.vo2.somepro去展现数据;但在做基于该内联字段的排序时,会出现问题。该问题通过重写DataGridColumn的deriveComplexColumnData和complexColumnSortCompare方法,修改flex的代码,可以得到解决。但后来发现,尽管使用该方法后,可以做基于内联对象属性的排序了,但在对datagrid的dataProvider(一个arrayCollection)做getItemIndex(也包括removeItemAt/addItemAt等,内部是调用了getItemIndex的)时,会出现另一个bug:
查找条件必须至少包含一个排序域值
Find criteria must contain at least one sort field value
Error: 查找条件必须至少包含一个排序域值。
	at mx.collections::Sort/findItem()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\Sort.as:541]
	at mx.collections::ListCollectionView/getItemIndex()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:652]
	at com.bcia.fids.ops.depf::FidsDepf/delFidsDepfInGridResult()[D:\FIDS\flexsrc\FidsFlex\src\com\bcia\fids\ops\depf\FidsDepf.mxml:233]
	at com.bcia.fids.ops.depf::FidsDepf/messageHandler()[D:\FIDS\flexsrc\FidsFlex\src\com\bcia\fids\ops\depf\FidsDepf.mxml:187]
	at com.bcia.fids.ops.depf::FidsDepf/flexMessageResultHandler()[D:\FIDS\flexsrc\FidsFlex\src\com\bcia\fids\ops\depf\FidsDepf.mxml:316]
	at com.bcia.fids.ops.depf::FidsDepf/___FidsDepf_Operation17_result()[D:\FIDS\flexsrc\FidsFlex\src\com\bcia\fids\ops\depf\FidsDepf.mxml:50]
	at flash.events::EventDispatcher/dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at mx.rpc::AbstractOperation/http://www.adobe.com/2006/flex/mx/internal::dispatchRpcEvent()[E:\dev\4.x\frameworks\projects\rpc\src\mx\rpc\AbstractOperation.as:249]
	at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::resultHandler()[E:\dev\4.x\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:318]
	at mx.rpc::Responder/result()[E:\dev\4.x\frameworks\projects\rpc\src\mx\rpc\Responder.as:56]
	at mx.rpc::AsyncRequest/acknowledge()[E:\dev\4.x\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:84]
	at NetConnectionMessageResponder/resultHandler()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\channels\NetConnectionChannel.as:547]
	at mx.messaging::MessageResponder/result()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\MessageResponder.as:235]
如在datagrid中使用nested object无法排序一样,这也是flex的一个bug:
http://stackoverflow.com/questions/5895483/flex-find-criteria-must-contain-at-least-one-sort-field-value
http://bugs.adobe.com/jira/browse/SDK-23643?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel
https://bugs.adobe.com/jira/browse/SDK-9801
报错的代码在Sort.as的findItem方法中:
public function findItem(items:Array,
                             values:Object,
                             mode:String,
                             returnInsertionIndex:Boolean = false,
                             compareFunction:Function = null):int
    {
...
if (fieldsForCompare.length == 0)
                {
                	message = resourceManager.getString(
                		"collections", "findRestriction");
                    throw new SortError(message);
                }
...
}


修改FLEX源代码,还怕改出其他问题来,不是上上之选。目前已知的可采用的变通方法有两个:
仍然使用nested object,新建一个arrayCollection2,和作为datagrid的dataProvider的arrayCollection使用相同的source;对arrayCollection的增删改,全部通过操作arrayCollection2来完成,并refresh arrayCollection。目前采用的就是这种方法,可以规避“Find criteria must contain at least one sort field value”这个bug的出现。
采用变通的方式来展现nested object(此种方式未验证正确性,不过应该可行):
DataGrid error - Find criteria must contain at least one sort field value
http://www.flexonjava.net/2010/09/datagrid-error-find-criteria-must.html
引用
I got the above error message while doing some random tests on my current Flex application. This always seemed to be happening under the following scenario... a DataGrid was on the screen, the grid was binded to a collection (myVosArrayCollection). One of the gird columns data fields was pointing to a nested value (myVO.field.child) :
<mx:DataGridColumn dataProvider="{myVosArrayCollection}" dataField="field.child".../>
It seems like Flex has a problem dealing with nested objects for dataGrid column dataField. My solution is adding a wrapper getter on myVO.field.child , for me this is only natural as I'm using a two level VOs hierarchy exactly for these sort of scenarios, the BaseVO and the VO it self (but that's something I'll cover on a different post). MyVo now have a new getter:
public class MyVO
 {
     private var field:Object;
  
     public function get fieldChild():Object
     {
         return field.child;
     }
 }
my DataGrid now has the following setup:
<mx:DataGridColumn dataProvider="{myVosArrayCollection}" dataField="fieldChild".../>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics