2013-07-25 6 views
1

필자에게는 ExtJS 그리드 (버전 4.2.1)가 있습니다. 버퍼링되고 무한 스크롤됩니다. REST 프록시가있는 상점에 의해 채워집니다.ExtJS 무한 그리드가 영원히로드됩니다 (totalProperty == pageSize)

/endpoints.json?_dc=1374783152564&page=1&start=0&limit=30&sort=checkedAt&dir=desc&query=codian 

JSON 응답 (1 개 결과립니다)입니다 :

요청

이 이루어집니다

{"links":[], 
"count":30, 
"totalCount":30, 
"endpointList":[{ 
    "links":[{"rel":"self","href":"http://localhost:8080/endpointmanager/endpoints/3"}, 
      {"rel":"currentStatus","href":"http://localhost:8080/endpointmanager/endpoints/3/status"}, 
      {"rel":"statusLog","href":"http://localhost:8080/endpointmanager/endpoints/3/statuslog"}], 
    "name":"Codian MCU",  
    "managed":false, 
    "updateInterval":3, 
    "checkedAt":null, 
    "timeout":60, 
    "deviceType":"Codian MCU", 
    "currentStatus":{"links":[], 
        "connected":false, 
        "description":"Unknown Status"}}]} 

응답은 정확히 내가이 쿼리에 대해 기대하는 것입니다. 1 페이지. 30 totalCount.

{"links":[],"count":0,"totalCount":30,"endpointList":[]} 

이뿐만 아니라 나에게 좋아 보인다 : 다음 페이지를 요청

이 응답을 반환합니다.

문제는 ExtJS입니다. 내 저장소의 pageSize == 내 요청에 의해 반환 된 totalCount 속성이 그리드를 회전시킬 때; 무한히 또는 응답의 totalCount! = pageSize까지로드됩니다.

의 ExtJS이 무한로드 중 예외를 발생 (EXT-모든 debug.js : 104,512) :

Uncaught Error: NotFoundError: DOM Exception 8 

Ext.view.NodeCache.scroll 코드로부터 주변 :

scroll: function(newRecords, direction, removeCount) { 
    var me = this, 
     elements = me.elements, 
     recCount = newRecords.length, 
     i, el, removeEnd, 
     newNodes, 
     nodeContainer = me.view.getNodeContainer(), 
     frag = document.createDocumentFragment(); 


    if (direction == -1) { 
     for (i = (me.endIndex - removeCount) + 1; i <= me.endIndex; i++) { 
      el = elements[i]; 
      delete elements[i]; 
      el.parentNode.removeChild(el); 
     } 
     me.endIndex -= removeCount; 


     newNodes = me.view.bufferRender(newRecords, me.startIndex -= recCount); 
     for (i = 0; i < recCount; i++) { 
      elements[me.startIndex + i] = newNodes[i]; 
      frag.appendChild(newNodes[i]); 
     } 
     nodeContainer.insertBefore(frag, nodeContainer.firstChild); 
    } 


    else { 
     removeEnd = me.startIndex + removeCount; 
     for (i = me.startIndex; i < removeEnd; i++) { 
      el = elements[i]; 
      delete elements[i]; 
      el.parentNode.removeChild(el); 
     } 
     me.startIndex = i; 


     newNodes = me.view.bufferRender(newRecords, me.endIndex + 1); 
     for (i = 0; i < recCount; i++) { 
      elements[me.endIndex += 1] = newNodes[i]; 
      frag.appendChild(newNodes[i]); 
      Uncaught Error: NotFoundError: DOM Exception 8 (repeated 5 times) 
     } 
     nodeContainer.appendChild(frag); 
    } 

    me.count = me.endIndex - me.startIndex + 1; 
} 

내 눈금 :

/** 
* TODO Known Defects: If the size of the result set returned by the search 
* filter == pageSize then the grid loads forever. The requests and responses 
* look correct, but an exception is thrown in extjs 
*/ 

Ext.Loader.setPath('Ext.ux', 'resources/js/extjs/examples/ux'); 
Ext.require([ 'Ext.grid.*', 'Ext.data.*', 'Ext.util.*', 
'Ext.grid.plugin.BufferedRenderer', 'Ext.ux.form.SearchField' ]); 

Ext.onReady(function() { 

    Ext.QuickTips.init(); 

    Ext.define('Endpoint', { 

     extend : 'Ext.data.Model', 
     fields : [ { 
      name : 'deviceType', 
      type : 'string', 
     }, { 
      name : 'name', 
      type : 'string', 
     }, { 
      name : 'managed', 
      type : 'boolean', 
     }, { 
      name : 'updateInterval', 
      type : 'int', 
     }, { 
      name : 'timeout', 
      type : 'int', 
     }, { 
      name : 'checkedAt', 
      type : 'string', 
     }, { 
      name : 'currentStatus', 
      mapping : 'currentStatus.description', 
      type : 'string', 
     } ], 
    }); 

    var store = new Ext.create('Ext.data.Store', { 
     id : 'store', 
     model : 'Endpoint', 

     autoLoad : true, 
     buffered : true, 
     pageSize : 30, 
     leadingBufferZone : 5, 
     remoteFilter : true, 
     remoteSort : true, 

     sorters : [ { 
      property : 'checkedAt', 
      direction : 'desc' 
     } ], 

     listeners : { 
      totalcountchange : onStoreSizeChange 
     }, 

     proxy : { 
      type : 'rest', 
      url : '/endpointmanager/endpoints.json', 
      simpleSortMode : true, 
      filterParam : 'query', 
      encodeFilters : function(filters) { 
       return filters[0].value; 
      }, 
      reader : { 
       type : 'json', 
       root : 'endpointList', 
       totalProperty : 'totalCount', 
      }, 
      writer : { 
       type : 'json', 
      }, 
     }, 
    }); 

    function onStoreSizeChange() { 
     grid.down('#status').update({ 
      count : store.getTotalCount() 
     }); 
    } 

    var grid = Ext 
      .create(
        'Ext.grid.Panel', 
        { 

         store : store, 
         renderTo : 'endpoint-grid', 
         height : 600, 
         forceFit : true, 
         columnLines : true, 
         stripeRows : true, 
         loadMask : true, 
         multiselect : true, 
         viewConfig : { 
          trackOver : false, 
          emptyText : '<h1 style="margin:20px">No matching endpoints found</h1>' 
         }, 
         selModel : { 
          pruneRemoved : false 
         },        

         columns : [ { 
          xtype : 'checkcolumn', 
          header : 'Managed', 
          dataIndex : 'managed', 
          width : 100, 
          editor : { 
           xtype : 'checkbox', 
           cls : 'x-grid-checkheader-editor' 
          }, 
         }, { 
          header : 'Checked At', 
          dataIndex : 'checkedAt', 
          renderer : dateConverter, 
          width : 160, 
         }, { 
          header : 'Device Type', 
          dataIndex : 'deviceType', 
          width : 160, 
         }, { 
          header : 'Name', 
          dataIndex : 'name', 
          width : 160, 
          flex : 1, 
         }, { 
          header : 'Update Interval (sec)', 
          dataIndex : 'updateInterval', 
          width : 160, 
          editor : { 
           xtype : 'numberfield', 
           allowBlank : false, 
           minValue : 10, 
           maxValue : 2600000 
          }, 
         }, { 
          header : 'Timeout (sec)', 
          dataIndex : 'timeout', 
          width : 160, 
          editor : { 
           xtype : 'numberfield', 
           allowBlank : false, 
           minValue : -1, 
           maxValue : 3600, 
          } 
         }, { 
          header : 'Status', 
          dataIndex : 'currentStatus', 
          width : 160, 
         } ], 

         dockedItems : [ 
           { 
            xtype : 'toolbar', 
            dock : 'top', 
            items : [ 
              { 
               width : 400, 
               fieldLabel : 'Search', 
               labelWidth : 50, 
               xtype : 'searchfield', 
               store : store 
              }, 
              '->', 
              { 
               xtype : 'component', 
               itemId : 'status', 
               tpl : 'Matching Endpoints: {count}', 
               style : 'margin-right:5px' 
              } ] 

           }, 
           { 
            xtype : 'toolbar', 
            cls : 'listFooter', 
            dock : 'bottom', 
            items : [ 
              { 
               xtype : 'tbfill' 
              }, 
              { 
               text : 'remove', 
               cls : 'gridButton', 
               iconCls : 'icon-delete', 
               handler : function() { 
                var selection = grid 
                  .getView() 
                  .getSelectionModel() 
                  .getSelection()[0]; 
                if (selection) { 
                 store 
                   .remove(selection); 
                } 
               } 
              }, 
              '-', 
              { 
               text : 'edit', 
               cls : 'gridButton', 
               iconCls : 'icon-edit', 
               handler : function() { 
                store 
                  .insert(
                    0, 
                    new Endpoint()); 
               }, 
              }, 
              '-', 
              { 
               text : 'inline', 
               cls : 'gridButton', 
               iconCls : 'icon-add', 
               handler : function() { 
                store 
                  .insert(
                    0, 
                    new Endpoint()); 
               }, 
              }, 
              '-', 
              { 
               text : 'add', 
               cls : 'gridButton', 
               iconCls : 'icon-add', 
               handler : function() { 
                window.location = 'endpointManagementAdd'; 
               }, 
              } ], 
           } ], 
        }); 

    var task = { 
     run : function() { 
      store.load(); 
     }, 
     interval : 30000 
    }; 

    // kick-off refresh task 
    Ext.TaskManager.start(task); 

}); 

function dateConverter(data, cell, record, rowIndex, columnIndex, store) { 
    if (data == "") { 
return; 
    } 

    var dt = new Date(parseInt(data)); 

    return dt.toLocaleString(); 
}; 

누구든지이 문제가 발생 했습니까? ExtJS에서 던져진 예외를 해결할 수있는 방법이 있는지,이 동작을 트리거하기 위해 내가하고있는 비정상적인 것이 있는지 아닌지 궁금하다. 어떤 통찰력이라도 대단히 감사합니다. 그리드는이 결함 하나를 제외하고는 훌륭하게 작동합니다.

+0

죄송합니다. 최근 ExtJS 릴리스의 무한 표가 실제로 버그가 있습니다. 지금 스레드를 찾을 수없는 것 같지만 ExtJS 포럼에서 비슷한 문제가보고되었습니다. 프레임 워크의 이전 버전을 사용하여 여전히 문제가 있는지 확인하려고합니다. – drew630

+0

머리를 주셔서 감사합니다. 내가 주위에 일을 알아낼 수 없다면 일부 파고 및 이전 릴리스를 시도 할 것입니다 ... –

+0

내 경험에서 신뢰할 수있는 무한 그리드가 ExtJS 버전이 없습니다. 나는 각 릴리스가 조금 더 나아 졌다고 말할 것이다. 그러나 화성 - 레드가 4.2.2에 대해 말한 것이 사실 일 것이라고 기대하고있다. – FoxMulder900

답변

2

"대답"에 적합한 지 확실하지 않지만이 순간에 덧글을 추가할만한 충분한 평판이 없습니다. 4.2.1에서 비슷한 문제가 발생하여 4.2.2에서 해결 된 것으로 나타났습니다. 현재로서는 해당 버전을 얻으려면 프리미엄 지원이 필요하므로 도움이되지 않을 수 있습니다. 이전 버전을 사용해 보지 않았습니다. Ext JS 4.2 버전이 필요한 타사 라이브러리를 사용하고 있습니다.

어쨌든 나는 Sencha 포럼에서 DOM 예외와 관련된 문제와로드 표시기의 일반적으로 이상한 동작에 대해 게시했습니다. 4.2.2에서 문제가 해결되었다는 것을 알게되었을 때, 서버에서 다시 보내지는 총계가 데이터 저장소 페이지 크기와 같고 문제를 재현 할 수없는이 시나리오를 시도했습니다.

0

Ext.define('NodeCacheOverride', { 
override: 'Ext.view.NodeCache', 
/** 
* Appends/prepends records depending on direction flag 
* @param {Ext.data.Model[]} newRecords Items to append/prepend 
* @param {Number} direction `-1' = scroll up, `0` = scroll down. 
* @param {Number} removeCount The number of records to remove from the end. if scrolling 
* down, rows are removed from the top and the new rows are added at the bottom. 
*/ 
scroll: function (newRecords, direction, removeCount) { 
    var me = this, 
     elements = me.elements, 
     recCount = newRecords.length, 
     i, el, removeEnd, 
     newNodes, 
     nodeContainer = me.view.getNodeContainer(), 
     frag = document.createDocumentFragment(); 

    // Scrolling up (content moved down - new content needed at top, remove from bottom) 
    if (direction == -1) { 
     for (i = (me.endIndex - removeCount) + 1; i <= me.endIndex; i++) { 
      el = elements[i]; 
      delete elements[i]; 
      el.parentNode.removeChild(el); 
     } 
     me.endIndex -= removeCount; 

     // grab all nodes rendered, not just the data rows 
     newNodes = me.view.bufferRender(newRecords, me.startIndex -= recCount); 
     for (i = 0; i < recCount; i++) { 
      elements[me.startIndex + i] = newNodes[i]; 
      frag.appendChild(newNodes[i]); 
     } 
     nodeContainer.insertBefore(frag, nodeContainer.firstChild); 
    } 

    // Scrolling down (content moved up - new content needed at bottom, remove from top) 
    else { 


     if(me.count == me.endIndex + 1) return; // Override modification 

     removeEnd = me.startIndex + removeCount; 
     for (i = me.startIndex; i < removeEnd; i++) { 
      el = elements[i]; 
      delete elements[i]; 
      el.parentNode.removeChild(el); 
     } 
     me.startIndex = i; 
     // grab all nodes rendered, not just the data rows 
     newNodes = me.view.bufferRender(newRecords, me.endIndex + 1); 
     for (i = 0; i < recCount; i++) { 
      elements[me.endIndex += 1] = newNodes[i]; 
      frag.appendChild(newNodes[i]); 
     } 
     nodeContainer.appendChild(frag); 
    } 
    // Keep count consistent. 
    me.count = me.endIndex - me.startIndex + 1; 
} 
같은 재정의를 사용하여 시도 할 수 있습니다

});

보기를 선언하기 전에 이 포함되어 있는지 확인하십시오. 문제를 재현하지 못했습니다. 완전히 테스트되지 않았습니다., 그래서 그것이 밖으로 작동하지 않으면, 당신의 나머지 부분이 걸리는 예외를 처리 할 때까지 약간 조정할 것을 권할 것입니다. 렌더링 작업.

희망 솔루션은 올바른 솔루션을 찾는 데 도움이됩니다.

관련 문제