2011-08-22 3 views
2

나는 내 요구 사항에 맞게 Ajax-Loading Example을 확장 할 수있었습니다.SlikGrid 가상 스크롤 - 거대한 데이터 세트

현재 구현에서 slick.remotemodel.js의 로더에는 javascript 객체의 배열 인 data라는 변수가 있습니다. 이 배열은 그리드의 데이터 소스입니다. DOM이 페이지 크기의 행만 렌더링 되더라도 스크롤을 계속하면 자바 스크립트 배열이 계속 커집니다.

자바 스크립트 개체의 크기의 상한선은 무엇입니까? 메모리가 부족할 가능성이 있습니까? 내 데이터 세트가 여러 열 ~ 10의 ~ 125000 행의 순서라고 가정 해 보겠습니다. 데이터 세트의 크기를 정의하는 데 더 많은 정보가 필요할 수도 있지만 위의 정보를 통해 누군가가 입력을 제공 할 수 있습니까?

위의 시나리오를 처리하기 위해 코드를 업데이트했습니다. 내 편집을 참조하십시오. 제가 누락 된 것이 있으면 알려주세요.

편집 : 내 솔루션은 onsuccess 메서드에서 clear 메서드를 호출하여 데이터 배열에 PAGESIZE # 개의 항목 만 있는지 확인했습니다.

(function ($) { 
    /*** 
    * Ajax loading example which is an extension 
    * of the http://mleibman.github.com/SlickGrid/examples/example6-ajax-loading.html 
    * example. 
    */ 
    function RemoteModel() { 
     // private 

     var fromPage = 0; 
     var rows = 0; 

     var PAGESIZE = 250; 
     var data = { length: 0 }; 
     var h_request = null; 
     var req = null; // ajax request 

     // events 
     var onDataLoading = new Slick.Event(); 
     var onDataLoaded = new Slick.Event(); 


     function init() { 
     } 


     function isDataLoaded(from, to) { 
      for (var i = from; i <= to; i++) { 
       if (data[i] == undefined || data[i] == null) 
        return false; 
      } 

      return true; 
     } 


     function clear() { 
      for (var key in data) { 
       delete data[key]; 
      } 
      data.length = 0; 
     } 


     function ensureData(from, to) { 

      if (req) { 
       req.abort(); 

       for (var i = req.fromPage; i <= req.toPage; i++) 
        data[i * PAGESIZE] = undefined; 
      } 

      if (from < 0) 
       from = 0; 

      fromPage = Math.floor(from/PAGESIZE); 
      var toPage = Math.floor(to/PAGESIZE); 

      while (data[fromPage * PAGESIZE] !== undefined && fromPage < toPage) 
       fromPage++; 

      while (data[toPage * PAGESIZE] !== undefined && fromPage < toPage) 
       toPage--; 

      rows = (((toPage - fromPage) * PAGESIZE) + PAGESIZE); 

      if (fromPage > toPage || ((fromPage == toPage) && data[fromPage * PAGESIZE] !== undefined)) { 

       // TODO: look-ahead 
       return; 
      } 

      var url = "" ; // IMPORTANT : you should set this to your url which returns the data 

      if (h_request != null) { 
       clearTimeout(h_request); 
      } 

      h_request = setTimeout(function() { 

       for (var i = fromPage; i <= toPage; i++) 
        data[i * PAGESIZE] = null; // null indicates a 'requested but not available yet' 

       onDataLoading.notify({ from: from, to: to }); 

       req = $.ajax({ 
        url: url, 
        dataType: 'json', 
        success: function (response) { 
         onSuccess(response); 
        }, 
        error: function() { 
         onError(fromPage, toPage); 
        } 
       }); 


       req.fromPage = fromPage; 
       req.toPage = toPage; 

      }, 100); 
     } 


     function onError(fromPage, toPage) { 
      alert("error loading pages " + fromPage + " to " + toPage); 
     } 

     function onSuccess(response) { 

      //Solution to keep the data array bounded to pagesize: Call the clear method to have only PAGESIZE elements in the data array at any given point 
      clear(); 

     //The visisble # of rows in the viewport could be only ~20 but 
      // i'm populating PageSIZE which acts like the client-side cache, in my case 250, 
     // so that I avoid too many server hops 
      var from = fromPage * PAGESIZE, to = from + PAGESIZE; 

      data.length = response.count; 

      for (var i = 0; i < response.Fields.length; i++) { 
       data[from + i] = response.Fields[i]; 
       data[from + i].index = from + i; 
      } 

      req = null; 

      onDataLoaded.notify({ from: from, to: to }); 
     } 


     function reloadData(from, to) { 
      for (var i = from; i <= to; i++) 
       delete data[i]; 

      ensureData(from, to); 
     } 


     init(); 

     return { 
      // properties 
      "data": data, 

      // methods 
      "clear": clear, 
      "isDataLoaded": isDataLoaded, 
      "ensureData": ensureData, 
      "reloadData": reloadData, 

      // events 
      "onDataLoading": onDataLoading, 
      "onDataLoaded": onDataLoaded 
     }; 
    } 

    // Slick.Data.RemoteModel 
    $.extend(true, window, { Slick: { Data: { RemoteModel: RemoteModel}} }); 
})(jQuery); 
enter code here 

감사

답변

2

내 솔루션 확인 데이터 배열 항목의 PAGESIZE #을 가지고 있는지 확인하기 위해 onsuccess는 방법에 맑은 메소드를 호출하는 것이다. 이것은 필요한 자바 스크립트 객체 배열에만 데이터를 보관하고 나머지는 정의되지 않음으로 설정해야합니다.

+0

그리드를 편집 할 수 있었습니까? 사용자가 화면에서 벗어날 수있는 요소의 울림을 선택한 다음 삭제할 수 있습니까? – Daryn