2009-09-02 9 views
8

Tamam, bir XMLListCollection alfabetik sırayla sıralıyorum. Yine de bir sorunum var. Değer "ALL" ise, listenin ilk olmasını istiyorum. Çoğu durumda, bu zaten gerçekleşir ancak sayılar olan değerler "ALL" dan önce sıralanır. DataProvider'ımdaki ilk seçim ve her zaman alfabetik olanı olmak için "ALL" yi istiyorum.Esnek: Sırala - Özel bir karşılaştırma yazısı yazılıyor mu?

Kendi sıralama işlevimi yazmaya çalışıyorum. Değerlerden birinin olup olmadığını kontrol edebilmem için bir yol var mı, ve eğer değerler üzerinde düzenli bir karşılaştırma yapmak için bunu söylemezseniz?

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; 

Yapmak ne çalışıyorum bir çözüm var mı: İşte

ben ne var?

+0

Her ikisi de' hepsi 'ise ne olur? –

+0

Bunun asla olmayacağını söylemek isterim. Ama evet biliyorum ki bu asla lol değildir. Ellerin aynı olup olmadığını kontrol etmek için elden başka bir ifade daha ekleyeceğim ve geri dönüş 0 doğru. Teşekkürler. –

cevap

8

İyi bir şey denedim ve gerçekten çalıştığını gerçekten şaşırdım, ama yaptığım şey buydu.

Sıralama sınıfı, internalCompare adı verilen özel bir işleve sahiptir. Özel olduğu için onu arayamazsın. AMA, compareFunction olarak adlandırılan bir alıcı işlevi vardır ve karşılaştırma işlevi tanımlanmamışsa, internalCompare işlevine bir başvuru döndürür. Yani yaptığım bu referansı aldım ve sonra ara.

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

Ayrıca, sınıfın bir örneğini veya statik bir üyesini de oluşturabilirsiniz, böylece bir karşılaştırma yapıldığında yeni bir sıralama oluşturmanız gerekmez. –

+0

@Kathy, iyi nokta. –

+0

nice, good gem :) – Tox

14

John Isaacks gelen çözüm müthiş, ama o değişkeni "alanlar" unuttu ve onun örneği (Strings hariç) daha karmaşık nesneler için çalışmıyor

Örnek:

// 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

İlk bakışta yanlış olduğunu düşündüm ama Adobe bir kez daha berbat olmayı başardı. InternalCompare işlevi, işlev parametresi yerine örnek alanlarını kontrol eder. Adobe'nin mücevherlerinden bir diğeri ... –

+0

Bu çok yardımcı oldu. Bunun yerine String.localeCompare() kullanmayı denedim, ancak çok sık çağrılan sıralamanın bazı kötü yan etkileri var. –

0

Teşekkürler, bu çok yardımcı oldu. Bizim durumumuzda, alt kısımdaki tüm boş satırlara (DataGrid'de) ihtiyacımız vardı. Tüm boş olmayan satırlar normal şekilde sıralanmalıdır. Satır verilerimiz dinamik nesnelerdir (JSON'dan dönüştürülür) - ValidationHelper.hasData() öğesine yapılan çağrı, satırın boş olup olmadığını kontrol eder. alfabetik oldu durumumdan, çalışmak için ben bu yaklaşımları bulamadık

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

: Nedense alanlarına bazen yerine SortFields ait dataField String değeri, 'alanlar' özelliğini ayarlamadan önce dolayısıyla çeki içerirler Dizelerin bir listesi ve sonra listenin sonunda 'Yeni oluştur ...' öğesini ekleyin.

İşlerimi ele alma biçimim birazcık yetersiz, ancak güvenilir.

Ben sıralanmış benim Strings ArrayCollection, bu yüzden gibi bir alfa tür, orgNameList seslendi:
var alphaSort:Sort = new Sort(); 
    alphaSort.fields = [new SortField(null, true)]; 
    orgNameList.sort = alphaSort; 
    orgNameList.refresh(); 

Sonra, yeni bir ArrayCollection içine sıralı listenin elemanlarını Kopyalanan customerDataList
aradı. Sonuç olarak, ArrayCollection öğesinin yeni öğeleri alfabetik sıradadır, ancak Sort nesnesinin etkisi altında değildir. Yani, yeni bir eleman eklemek ArrayCollection'un sonuna ekleyecektir. Aynı şekilde, ArrayCollection'daki belirli bir dizine bir öğe eklenmesi de beklendiği gibi çalışacaktır.

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

Daha sonra yeni oluştur ...'item, like this:

if(userIsAllowedToCreateNewCustomer) 
    { 
     customerDataList.addItem(CREATE_NEW); 
     customerDataList.refresh(); 
    }