2009-09-02 16 views
8

OK, tôi sắp xếp một XMLListCollection theo thứ tự bảng chữ cái. Tôi có một vấn đề mặc dù. Nếu giá trị là "TẤT CẢ" tôi muốn nó là đầu tiên trong danh sách. Trong hầu hết các trường hợp, điều này đã xảy ra nhưng các giá trị là các số đang được sắp xếp trước "ALL". Tôi muốn "TẤT CẢ" luôn là lựa chọn đầu tiên trong dataProvider của tôi và sau đó là phần còn lại theo thứ tự chữ cái.Flex: Sắp xếp - Viết một hàm so sánh tùy chỉnh?

Vì vậy, tôi đang cố gắng viết chức năng sắp xếp của riêng mình. Có cách nào tôi có thể kiểm tra nếu một trong các giá trị là tất cả, và nếu không nói với nó để làm so sánh thường xuyên về các giá trị?

Dưới đây là những gì tôi có:

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; 

Có một giải pháp cho những gì tôi đang cố gắng để làm gì?

+0

Điều gì xảy ra nếu cả hai đều là' tất cả '? –

+0

Tôi muốn nói rằng sẽ không bao giờ xảy ra. Nhưng có, tôi biết rằng không bao giờ là trường hợp lol. Tôi sẽ thêm một câu lệnh if khác trước khi tay kiểm tra chúng giống nhau và trả về 0 là đúng. Cảm ơn. –

Trả lời

8

Tôi đã thử một cái gì đó, và tôi thực sự ngạc nhiên khi nó thực sự hiệu quả, nhưng đây là những gì tôi đã làm.

Lớp sắp xếp có chức năng riêng được gọi là internalCompare. Vì nó là riêng tư, bạn không thể gọi nó. NHƯNG có một hàm getter được gọi là compareFunction, và nếu không có hàm so sánh nào được định nghĩa, nó trả về một tham chiếu đến hàm internalCompare. Vì vậy, những gì tôi đã làm là có được tham chiếu này và sau đó gọi nó.

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

Bạn cũng có thể làm cho một cá thể hoặc thành viên tĩnh của lớp, vì vậy bạn không phải tạo một sắp xếp mới mỗi lần so sánh được thực hiện. –

+0

@Kathy, điểm tốt. –

+0

đẹp, tốt đá quý :) – Tox

14

Các giải pháp từ John Isaacks là tuyệt vời, nhưng anh quên mất "cánh đồng" biến và gương sáng của mình không hoạt động cho các đối tượng phức tạp hơn (trừ Strings)

Ví dụ:

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

Thoạt nhìn tôi nghĩ bạn đã sai nhưng hóa ra Adobe quản lý để vít lên một lần nữa. Hàm internalCompare của chúng sẽ kiểm tra các trường instance thay vì tham số hàm. Tuy nhiên, một viên đá quý khác của Adobe ... –

+0

Điều này rất hữu ích. Tôi đã thử sử dụng String.localeCompare() thay vào đó, nhưng có một số tác dụng phụ khó chịu của việc sắp xếp được gọi quá thường xuyên –

0

Xin cảm ơn các bạn, điều này đã giúp ích rất nhiều. Trong trường hợp của chúng tôi, chúng tôi cần tất cả các hàng trống (trong một DataGrid) ở phía dưới. Tất cả các hàng không trống nên được sắp xếp bình thường. Dữ liệu hàng của chúng tôi là tất cả các đối tượng động (được chuyển đổi từ JSON) - cuộc gọi đến ValidationHelper.hasData() chỉ cần kiểm tra xem hàng có trống không. Đối với một số lý do các lĩnh vực đôi khi chứa DataField Chuỗi giá trị thay vì SortFields, do đó việc kiểm tra trước khi thiết lập thuộc tính 'lĩnh vực':

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

tôi không tìm thấy những phương pháp làm việc cho hoàn cảnh của tôi, mà là để alphabetize một danh sách các chuỗi và sau đó nối thêm một mục 'Tạo mới ...' ở cuối danh sách.

Cách tôi xử lý mọi thứ có chút không phù hợp nhưng đáng tin cậy.

tôi sắp xếp của tôi ArrayCollection của Strings, gọi orgNameList, với một loại alpha, như vậy:

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

Sau đó, tôi sao chép các phần tử của danh sách được sắp xếp thành một mới ArrayCollection, gọi customerDataList. Kết quả là các phần tử ArrayCollection mới theo thứ tự bảng chữ cái, nhưng không chịu ảnh hưởng của đối tượng Sort. Vì vậy, việc thêm một phần tử mới sẽ thêm nó vào cuối của ArrayCollection. Tương tự như vậy, việc thêm một mục vào một chỉ mục cụ thể trong ArrayCollection cũng sẽ hoạt động như mong đợi.

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

Sau đó, tôi vừa tacked vào 'Tạo mới ...'item, như thế này:

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