利用GroupingCollection幫你分組
Friday, March 26th, 2010有些時候我們有一堆資料物件, 需要根據物件的某個屬性值作分類, 最直接的方法就是跑個迴圈,如:
for each( var obj:Object in objectList )
{
//檢查obj的屬性值
if( obj.name in hash )
hash[obj.name].addItem( obj );
else
hash[obj.name] = new ArrayCollcetion([obj]);
}
//結果就是根據 obj.name 值分類好的hashmap
但我們可以利用Flex的GroupingCollection幫我們作這個工作, 而且過程封裝的更好:
var gping:Grouping = new Grouping();
var field:GroupingField = new GroupingField("你要分群組的屬性名稱");
//給予要群組的屬性, 可有多個GroupingField,
//會依序群組, 非常類似SQL::GROUP BY
gping.fields = [ field ];
groupingCollection.grouping = gping; //設定Grouping
groupingCollection.source = 原始資料 (通常是ArrayCollection);
groupingCollection.refresh(); //叫GroupingCollection開始工作
//重要的來了, 呼叫getRoot()取得GroupingCollection幫我們分群好的資料:
//結果通常是一個新的ArrayCollection, 裡面有多個Object ,
//每個 Object 有一個children屬性, 包了分組好的物件(原物件)
//Object本身有個預設的GroupLabel屬性,是根據你的資料內容的群組名稱
var result:Object = groupingCollection.getRoot();
預設的GroupLabel屬性名可以透過: Grouping#label 改成你想要的屬性名稱。
或許你會覺得這哪裡好,比一開始的還要複雜很多,其實他的威力不只是分群,還可以幫你分群作加總、求最大/最小值/平均值的功能呢,利用 SummaryRow 就可以輕鬆作到喔!
var smryField:SummaryField = new SummaryField("price","SUM"); //price ==> 要處理的屬性名稱
summaryRow.fields = [smryField];
var groupField:GroupingField = new GroupingField( "name" );
groupField.summaries = [ summarRow ] ;
...參考上方
上述結果是一個根據物件的”name”屬性分組,並且根據物件的”price”屬性作加總的GroupingCollection。同樣地利用getRoot();取得結果,可以看到新建立出來的Object#children除了有分群好的物件之外,還多出了SummaryObject,裡面就是幫我們算好的值。
補充:
自訂群組結點的標籤產生方式:
GroupingField#groupingFunction :
自訂group object#label的方法,在label不是單單靠某屬性值就能解決的情況,特別好用。 ex: 想作出一個group#lable = vo.name + vo.lastName + vo.id
signature:
groupingFunction(item:Object, field:GroupField):String
特別注意的: 當你覆寫了這個方法同時,記得也要覆寫 GroupingField#compareFunction,因為GroupingCollection建立GroupingCollectionView的時候會先對原始內容(來源ListCollectionView)排序,再產生Grouping(這樣效能比較好)。因此假設你的compareFunction並沒有寫好,那麼你會常常看到同一個群組結點標籤出現在不同的群組結點上。如果你不想用compareFunction,那麼,至少GroupingField#name的值對排序要有意義。
自訂群組結點物件內容:
GroupingField#groupingFunction :
產生group object的方法,當你不想要用預設的groupobject + label的方法,可用此方法自訂一Grouping Object的結構。
signature: myGroupObjectFunction(label:String):Object
