2009-09-02 6 views
8

OK、私はXMLListCollectionをアルファベット順にソートしています。私は1つの問題がある。値が "ALL"の場合は、リスト内の最初の値にします。ほとんどの場合、これはすでに発生していますが、数値である値は「ALL」の前にソートされています。私は "ALL"を常にdataProviderの最初の選択とし、残りのアルファベットを選択します。フレックス:並べ替え - カスタムcompareFunctionを記述する

私は自分のソート関数を作成しようとしています。値の1つがすべてであるかどうかを確認する方法はありますか?ここで

は私が持っているものです。

function myCompare(a:Object, b:Object, fields:Array = null):int 
{ 
    if(String(a).toLowerCase() == 'all') 
    { 
     return -1; 
    } 
    else 
     if(String(b).toLowerCase() == 'all') 
     { 
      return 1; 
     } 
    // NEED to return default comparison results here? 
} 

//------------------------------ 

var sort:Sort = new Sort(); 
sort.compareFunction = myCompare; 

は私がやろうとしています何のために解決策はありますか?

+0

両方が「すべて」の場合はどうなりますか? –

+0

それは決して起こらないと言いたいと思います。しかし、はい私はそれが決して笑ではないことを知っている。私は別のifステートメントを追加して、それらが同じで戻り値が0であることを確認します。ありがとう。 –

答えて

8

私は何かを試してみましたが、私は本当にそれが実際に働いて驚いていますが、ここで私がしたことです。

Sortクラスには、internalCompareという専用関数があります。それはプライベートなのであなたはそれを呼び出すことはできません。しかし、compareFunctionと呼ばれるゲッター関数があり、比較関数が定義されていなければ、internalCompare関数への参照を返します。だから、私がしたのはこの参照を取得し、それを呼び出すことでした。

private function myCompare(a:Object, b:Object, fields:Array = null):int 
{ 
    if(String(a).toLowerCase() == 'all') 
    { 
     return -1; 
    } 
    else if(String(b).toLowerCase() == 'all') 
    { 
     return 1; 
    } 
    // NEED to return default comparison results here? 
    var s:Sort = new Sort(); 
    var f:Function = s.compareFunction; 
    return f.call(null,a,b,fields); 
} 
+1

クラスのインスタンスまたは静的メンバーを作成することもできます。したがって、比較が行われるたびに新しいソートを作成する必要はありません。 –

+0

@Kathy、良い点。 –

+0

nice、good gem :) – Tox

14

ジョンIsaacksからのソリューションは素晴らしいですが、彼は、変数「フィールド」を忘れ、彼の例では、(文字列以外)をより複雑なオブジェクトでは動作しません

例:

// collection with custom objects. We want to sort them on "value" property 
// var item:CustomObject = new CustomObject(); 
// item.name = 'Test'; 
// item.value = 'Simple Value'; 

var collection:ArrayCollection = new ArrayCollection(); 
var s:Sort = new Sort(); 
s.fields = [new SortField("value")]; 
s.compareFunction = myCompare; 
collection.sort = s; 
collection.refresh(); 

private function myCompare(a:Object, b:Object, fields:Array = null):int 
{ 
    if(String((a as CustomObject).value).toLowerCase() == 'all') 
    { 
     return -1; 
    } 
    else if(String((b as CustomObject).value).toLowerCase() == 'all') 
    { 
     return 1; 
    } 
    // NEED to return default comparison results here? 
    var s:Sort = new Sort(); 
    s.fields = fields; 
    var f:Function = s.compareFunction; 
    return f.call(null,a,b,fields); 
} 
+0

一見したところ、私はあなたが間違っていると思っていましたが、Adobeがもう一度手放すことができました。それらのinternalCompare関数は、functionパラメーターの代わりにインスタンスフィールドをチェックします。アドビの宝石のもう一つの... –

+0

これは非常に有用だった。私は代わりにString.localeCompare()を使ってみましたが、それはあまりにも頻繁に呼び出される並べ替えのいくつかの厄介な副作用があります –

0

ありがとう、これは多くの助けとなりました。ここでは、下部にあるすべての空の行(DataGrid内)が必要でした。すべての空でない行は、通常どおりソートする必要があります。私たちの行データはすべてJSONから変換された動的オブジェクトです - ValidationHelper.hasData()の呼び出しは単に行が空であるかどうかをチェックします。アルファベット順になった私の状況、のために働くために、私はこれらのアプローチを見つけることができませんでした

private function compareEmptyAlwaysLast(a:Object, b:Object, fields:Array = null):int { 
    var result:int; 
    if (!ValidationHelper.hasData(a)) { 
     result = 1; 
    } else if (!ValidationHelper.hasData(b)) { 
     result = -1; 
    } else { 
     if (fields && fields.length > 0 && fields[0] is SortField) { 
      STATIC_SORT.fields = fields; 
     } 
     var f:Function = STATIC_SORT.compareFunction; 
     result = f.call(null,a,b,fields); 
    } 
    return result; 
} 
-1

:何らかの理由でフィールドが時々代わりのSortFieldsのデータフィールドの文字列値、「フィールド」プロパティを設定する前に、したがってチェックが含まれています文字列のリストを作成し、リストの最後に「新規作成...」という項目を追加します。

私は物事を扱う方法は、少し控えめですが、信頼性が高いです。

私は文字列の私のArrayCollectionをソートは、そうのように、アルファの並べ替えで、orgNameListと呼ば:

var alphaSort:Sort = new Sort(); 
    alphaSort.fields = [new SortField(null, true)]; 
    orgNameList.sort = alphaSort; 
    orgNameList.refresh(); 

をそれから私は、customerDataListと呼ばれる、新しいArrayCollectionにソートされたリストの要素をコピーしました。その結果、要素の新しいArrayCollectionはアルファベット順であるが、Sortオブジェクトの影響を受けない。したがって、新しい要素を追加すると、ArrayCollectionの末尾に追加されます。同様に、ArrayCollectionの特定のインデックスに項目を追加すると、期待どおりに機能します。

for each(var org:String in orgNameList) 
    { 
     customerDataList.addItem(org); 
    } 

次に、「新規作成」をタックしました。'のような項目:

if(userIsAllowedToCreateNewCustomer) 
    { 
     customerDataList.addItem(CREATE_NEW); 
     customerDataList.refresh(); 
    } 
関連する問題