2013-05-04 25 views
5

Dữ liệu tải tốt vào lưới, nhưng nó sẽ không sắp xếp.JQuery jqgrid không phân loại ở phía máy khách

Khi tôi nhấp vào tiêu đề bảng, các mũi tên sắp xếp xuất hiện, nhưng dữ liệu không được sắp xếp.

Cảm ơn.

$("#CompTable").jqGrid({ 
      url:'BomExplosionInJsonObj.asp' 
     , datatype: 'json' 
     , mtype: 'GET' 
     , height: 400 
     , colNames:['Part','Description','Src','Std Usage','Usage Inc Scrap','Rate Scrap','UOM','Item','Unit Cost','Stock'] 
     , colModel:[ {name:'COMP1_PART',index:'Part', width:120} 
           , {name:'WSCOMPDESC',index:'Desc', width:300} 
           , {name:'WSCOMPSRC',index:'Src', width:10} 
           , {name:'COMPUSAGE',index:'Usage', width:80, align:"right",sorttype:"float"} 
           , {name:'WSGROSSQTY',index:'TotUsage', width:80, align:"right",sorttype:"float"} 
           , {name:'COMPRATE_SCRAP',index:'Rate Scrap', width:80, align:"right",sorttype:"float"} 
           , {name:'COMPBASIC_UNIT',index:'UOM', width:20} 
           , {name:'COMP1_ITEM',index:'Item', width:20} 
           , {name:'WSCOMPUNITCOST',index:'UnitCost', width:80, align:"right",sorttype:"float"} 
           , {name:'WSCOMPQTYSTOCK',index:'Stock', width:80, align:"right",sorttype:"float"} 
          ] 
     , jsonReader: { 
       root:"rows" 
      , page: "page" 
      , total: "total" 
      , records: "records" 
      , repeatitems: false 
      , id: "0" 
      } 
     , multiselect: false 
     , caption: "Bom Detail" 
     , rowNum: 10000 
     , autoencode: true 
     , loadonce: true 
     , sortable: true 
     , loadComplete: function() {jQuery("#CompTable").trigger("reloadGrid");}// Call to fix client-side sorting 
    }); 
}); 

Dữ liệu JSON được trả lại (được đọc từ firebug).

{ 
    "total":"1" 
    ,"page":"1" 
    ,"records":"2" 
    , "rows": 
     [ 
     {"ID":1,"WSCOMPDESC":"ZYTEL E101L BLK MOUL ","WSCOMPUNITCOST":7.08,"WSCOMPSRC":"P ","WSCOMPQTYSTOCK":75,"COMPBASIC_UNIT":"KG ","COMPUSAGE":0.0034,"COMPRATE_SCRAP":0,"WSGROSSQTY":0.0034,"COMP1_PART":"1180019 ","COMP1_ITEM":" " 
     }, 
     {"ID":2,"WSCOMPDESC":"INSERT ","WSCOMPUNITCOST":1.89,"WSCOMPSRC":"P ","WSCOMPQTYSTOCK":400,"COMPBASIC_UNIT":"EA ","COMPUSAGE":2,"COMPRATE_SCRAP":0,"WSGROSSQTY":2,"COMP1_PART":"4OWE195689\/ISS 2 ","COMP1_ITEM":" " 
     } 
     ] 
    } 

Trả lời

15

Bạn đang có nhiều lỗi quan trọng:

  1. colModel chứa index thuộc tính đó là khác biệt so với giá trị của name cho cùng một mặt hàng. Đó là lỗi chính. Bạn không chỉ định bất kỳ tùy chọn sortname nào của jqGrid để các giá trị của thuộc tính index sẽ không bao giờ được máy chủ nhìn thấy. Nếu bạn sử dụng loadonce: true thì index thuộc tính phải giống với giá trị của name thuộc tính. Tôi khuyên bạn không bao gồm các thuộc tính index tại tất cả. Trong trường hợp index tính sẽ được khởi tạo với các giá trị của thuộc tính name
  2. Bạn sử dụng giá trị sai của id tài sản trong jsonReader: id: "0". Một khi sử dụng giá trị như vậy trong trường hợp của repeatitems: true. Trong trường hợp hàng sẽ được thể hiện trong đầu vào JSON là mảng. Vì vậy, giá trị 0 sẽ chính xác vì trong có thể được sử dụng làm chỉ mục trong mảng. Trong trường hợp sử dụng repeatitems: false các mục được biểu diễn các hàng dữ liệu trong đầu vào JSON là các đối tượng có các thuộc tính được đặt tên. Vì vậy, bạn nên sử dụng id: "ID" trong trường hợp của bạn. Hơn nữa, bạn không cần phải bao gồm trong jsonReader các thuộc tính có giá trị mặc định (root:"rows", page: "page") v.v.
  3. Vấn đề tiếp theo là việc sử dụng vô điều kiện reloadGrid bên trong của loadComplete. Bạn nên hiểu rằng loadComplete sẽ được thực hiện trên mỗi lần tải lại lưới (sự kiện tải lại cục bộ). Vì vậy, nó sẽ là sai làm cho tải lại vĩnh viễn của lưới điện. Ngoài ra, việc sử dụng reloadGrid bên trong của loadComplete không tốt so với một quan điểm khác. Nếu bạn kích hoạt reloadGrid sự kiện sẽ được thực hiện * ngay lập tức *, nhưng lưới không được xử lý việc tải trước đó. Vì vậy, nó sẽ chính xác hơn để kích hoạt tải lại bên trong của setTimeout với một khoảng thời gian nhỏ như 50 ms.
  4. Đề xuất cuối cùng là cách sử dụng kiểu viết mã của K&R (Kernighan và Ritchie). Việc định dạng mã mà bạn sử dụng bằng ngôn ngữ máy tính khác không quan trọng và điều quan trọng không phải là ngôn ngữ bạn tìm thấy tốt nhất để đọc. JavaScript có quyền riêng của nó.Một từ đó là chèn dấu chấm phẩy tự động (xem ví dụ here). Nếu bạn theo dõi K & R bạn sẽ không bao giờ có bất kỳ vấn đề nào với việc chèn dấu chấm phẩy tự động.
  5. Tôi khuyên bạn nên sử dụng height: "auto" nếu bạn cần hiển thị không nhiều hàng và sử dụng mẫu cột có thể giảm kích thước mã của bạn và đơn giản hóa việc quản lý mã.

Sau khi mô tả ở trên có thể thay đổi sẽ là một cái gì đó như dưới đây

var myFloatTemplate = { width: 80, align: "right", sorttype: "float" }; 

$("#CompTable").jqGrid({ 
    url: "BomExplosionInJsonObj.asp", 
    datatype: "json", 
    height: "auto", 
    colNames: ["Part", "Description", "Src", "Std Usage", "Usage Inc Scrap", "Rate Scrap", "UOM", "Item", "Unit Cost", "Stock"], 
    colModel: [ 
     {name: "COMP1_PART", width: 120}, 
     {name: "WSCOMPDESC", width: 300}, 
     {name: "WSCOMPSRC", width: 40}, 
     {name: "COMPUSAGE", template: myFloatTemplate}, 
     {name: "WSGROSSQTY", width: 120, template: myFloatTemplate}, 
     {name: "COMPRATE_SCRAP", width: 90, template: myFloatTemplate}, 
     {name: "COMPBASIC_UNIT", width: 60}, 
     {name: "COMP1_ITEM", width: 60}, 
     {name: "WSCOMPUNITCOST", template: myFloatTemplate}, 
     {name: "WSCOMPQTYSTOCK", template: myFloatTemplate} 
    ], 
    jsonReader: { 
     repeatitems: false, 
     id: "ID" 
    }, 
    caption: "Bom Detail", 
    rowNum: 10000, 
    autoencode: true, 
    loadonce: true, 
    sortable: true, 
    sortname: "COMP1_PART", 
    //sortorder: "desc", 
    loadComplete: function() { 
     var $self = $(this); 
     if ($self.jqGrid("getGridParam", "datatype") === "json") { 
      setTimeout(function() { 
       $self.trigger("reloadGrid"); // Call to fix client-side sorting 
      }, 50); 
     } 
    } 
}); 

Bản demo tương ứng là here. công trình sắp xếp địa phương và nó sẽ hiển thị kết quả như sau

enter image description here

CẬP NHẬT: Bắt đầu với phiên bản 4.12.0 free jqGrid ngã ba của jqGrid, mà tôi phát triển, hỗ trợ tùy chọn mới forceClientSorting: true. Nó hoạt động kết hợp với tùy chọn loadonce: true và cho phép tải trước tất cả dữ liệu từ phản hồi của máy chủ, sau đó sắp xếp dữ liệu cục bộ và chỉ sau đó mới hiển thị trang dữ liệu. Nó làm cho các trick với tải lại của lưới bên trong của setTimeout, bắt đầu trong loadComplete, được mô tả trong câu trả lời, không cần thiết. Bạn chỉ cần thay thế mã loadComplete ở trên thành một tùy chọn bổ sung forceClientSorting: true. Tùy chọn forceClientSorting: true có hai lợi ích bổ sung:

  1. Không thấy bất kỳ nhấp nháy nào sau khi hiển thị lưới đầu tiên (chưa phân loại);
  2. Hiệu suất của lưới là tốt hơn, đặc biệt nếu nó có nhiều hàng, bởi vì việc hiển thị lưới sẽ chậm hơn nhiều khi sắp xếp. Hơn nữa các trick với mô tả trong câu trả lời cũ hiển thị lưới, sau đó xóa nội dung (mà là từ từ quá) và sau đó một hiển thị lưới được sắp xếp một lần nữa.
+0

Đó là câu trả lời hay - cảm ơn. Các reloadgrid là một cái gì đó tôi tìm thấy trên một stackoverflow gọi về phân loại phía khách hàng. Chỉ cần bắt đầu với jqgrid, vì vậy hãy cố gắng hiểu nó hoạt động như thế nào. Cảm ơn bạn đã giúp đỡ. – Keith

+0

@Keith: Bạn được chào đón! – Oleg

0

Mã bạn đăng cho thấy rằng việc sắp xếp sẽ được thực hiện trên máy chủ chứ không phải trên máy khách. JqGrid của bạn sẽ đăng thông số sordsidx để cho phép bạn làm như vậy như là một phần của việc trả lại dữ liệu cho jqGrid.

Ex: C# MVC đang Controller, nơi phân trang cũng thực hiện

public ActionResult GetGridData(string sidx, string sord, int page, int rows, bool _search, string filters) 
{ 
... 
var pagedQuery = wholeDataSet.OrderBy(sidx + " " + sord).Skip((page - 1) * rows).Take(rows).ToList(); 
...