关注JEECG发展历程 关注最新动态和版本, 记录JEECG成长点滴 更新日志 - 技术支持 - 招聘英才

JEECG最新版本下载 JEECG智能开发平台 - 显著提高开发效率 常见问题 - 入门视频 - 参与开源团队

商务QQ: 69893005、3102411850 商务热线(5*8小时): 010-64808099 官方邮箱: jeecgos@163.com

查看: 8991|回复: 0

easyui大数据卡死问题解决方案

[复制链接]
发表于 2013-11-1 19:50:15 | 显示全部楼层 |阅读模式

easyui 数据行多行的时候再ie下会非常忙,自己尝试2000行基本上就卡死了,flex也有差不多的问题,但是flex有虚拟布局的选项,使用之后基本上就不会有什么问题了



但是easyui并没有这个选,在官网上面的插件去找了一个类似的功能,但是自己尝试了,他是使用的ajax调用的,并没有利用一次加载,分次加载的功能,所以自己修改了

下,一次加载数据,每次只渲染20-30行的样子,那么基本上就没有了卡死的问题了,放代码,如果有问题,可以自己调试下



使用方法添加view:scrollview

  1. /***
  2. * @author jueyue
  3. * @version1.0
  4. *虚拟布局,提供大数据量的布局方式,最好的方式是自己提供高度和宽度,默认高度25
  5. *特别是在有图片的情况下,请指定行高默认25px
  6. *如果修改高度 rowStyler 指定行高,不然不好对齐
  7. *一次加载数据多次渲染数据,所以ie下也不存在行数太多而不渲染失败的问题
  8. */
  9. var scrollview = $.extend({}, $.fn.datagrid.defaults.view, {
  10.         /***
  11.          * 渲染函数
  12.          * @param {} target
  13.          * @param {} container
  14.          * @param {} frozen
  15.          */
  16.         render : function(target, container, frozen) {
  17.                 var state = $.data(target, 'datagrid');
  18.                 var opts = state.options;
  19.                 var rows = this.rows || [];
  20.                 if (!rows.length) {
  21.                         return;
  22.                 }
  23.                 var fields = $(target).datagrid('getColumnFields', frozen);

  24.                 if (frozen) {
  25.                         if (!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))) {
  26.                                 return;
  27.                         }
  28.                 }

  29.                 var index = this.index;
  30.                 var classValue = '';
  31.                 var styleValue = '';
  32.                 var style = '';
  33.                 var table = ['<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>'];
  34.                 for (var i = 0; i < rows.length; i++) {
  35.                         var css = opts.rowStyler ? opts.rowStyler.call(target, index,
  36.                                         rows[i]) : '';
  37.                         if (typeof css == 'string') {
  38.                                 styleValue = css;
  39.                         } else if (css) {
  40.                                 classValue = css['class'] || '';
  41.                                 styleValue = css['style'] || '';
  42.                         }
  43.                         var cls = 'class="datagrid-row '
  44.                                         + (index % 2 && opts.striped ? 'datagrid-row-alt ' : ' ')
  45.                                         + classValue + '"';
  46.                                        
  47.                         if(frozen){
  48.                                 style = 'style="height:'+opts.rowHeight+'px;"'
  49.                         }else{
  50.                                 style = styleValue ? 'style="' + styleValue + '"' : 'style="height:25px;"';
  51.                         }
  52.                         var rowId = state.rowIdPrefix + '-' + (frozen ? 1 : 2) + '-'
  53.                                         + index;
  54.                         table.push('<tr id="' + rowId + '" datagrid-row-index="' + index
  55.                                         + '" ' + cls + ' ' + style + '>');
  56.                         table.push(this.renderRow.call(this, target, fields, frozen, index,
  57.                                         rows[i]));
  58.                         table.push('</tr>');

  59.                         // render the detail row
  60.                         if (opts.detailFormatter) {
  61.                                 table.push('<tr style="display:none;">');
  62.                                 if (frozen) {
  63.                                         table.push('<td colspan=' + (fields.length + 2)
  64.                                                         + ' style="border-right:0">');
  65.                                 } else {
  66.                                         table.push('<td colspan=' + (fields.length) + '>');
  67.                                 }
  68.                                 table.push('<div class="datagrid-row-detail">');
  69.                                 if (frozen) {
  70.                                         table.push(' ');
  71.                                 } else {
  72.                                         table.push(opts.detailFormatter.call(target, i, rows[i]));
  73.                                 }
  74.                                 table.push('</div>');
  75.                                 table.push('</td>');
  76.                                 table.push('</tr>');
  77.                         }
  78.                         index++;
  79.                 }
  80.                 table.push('</tbody></table>');
  81.                 $(container).html(table.join(''));
  82.                
  83.         },
  84.         /**
  85.          * 渲染行,这里个高度都是auto,可以在col里面来做style限制
  86.          * @param {} target
  87.          * @param {} fields
  88.          * @param {} frozen
  89.          * @param {} rowIndex
  90.          * @param {} rowData
  91.          * @return {}
  92.          */
  93.         renderRow : function(target, fields, frozen, rowIndex, rowData) {
  94.                 var opts = $.data(target, 'datagrid').options;

  95.                 var cc = [];
  96.                 //添加行号
  97.                 if (frozen && opts.rownumbers) {
  98.                         var rownumber = rowIndex + 1;
  99.                         if (opts.pagination) {
  100.                                 rownumber += (opts.pageNumber - 1) * opts.pageSize;
  101.                         }
  102.                         cc.push('<td class="datagrid-td-rownumber"><div class="datagrid-cell-rownumber" style="text-align:center">'
  103.                                                         + rownumber + '</div></td>');
  104.                 }
  105.                 for (var i = 0; i < fields.length; i++) {
  106.                         var field = fields[i];
  107.                         var col = $(target).datagrid('getColumnOption', field);
  108.                         if (col) {
  109.                                 var value = rowData[field]; // the field value
  110.                                 var css = col.styler
  111.                                                 ? (col.styler(value, rowData, rowIndex) || '')
  112.                                                 : '';
  113.                                 var classValue = '';
  114.                                 var styleValue = '';
  115.                                 if (typeof css == 'string') {
  116.                                         styleValue = css;
  117.                                 } else if (cc) {
  118.                                         classValue = css['class'] || '';
  119.                                         styleValue = css['style'] || '';
  120.                                 }
  121.                                 var cls = classValue ? 'class="' + classValue + '"' : '';
  122.                                 var style = col.hidden
  123.                                                 ? 'style="display:none;' + styleValue + '"'
  124.                                                 : (styleValue ? 'style="' + styleValue + '"' : '');

  125.                                 cc.push('<td field="' + field + '" ' + cls + ' ' + style + '>');

  126.                                 if (col.checkbox) {
  127.                                         style = 'height:15;';
  128.                                 } else if (col.expander) {
  129.                                         style = "text-align:center;height:15;";
  130.                                 } else {
  131.                                         style = styleValue;
  132.                                         if (col.align) {
  133.                                                 style += ';text-align:' + col.align + ';'
  134.                                         }
  135.                                         if (!opts.nowrap) {
  136.                                                 style += ';white-space:normal;height:auto;';
  137.                                         } else if (opts.autoRowHeight) {
  138.                                                 style += ';height:auto;';
  139.                                         }
  140.                                 }

  141.                                 cc.push('<div style="' + style + '" ');
  142.                                 if (col.checkbox) {
  143.                                         cc.push('class="datagrid-cell-check');
  144.                                 } else {
  145.                                         cc.push('class="datagrid-cell ' + col.cellClass);
  146.                                 }
  147.                                 cc.push('">');

  148.                                 if (col.checkbox) {
  149.                                         cc.push('<input type="checkbox" name="' + field
  150.                                                         + '" value="' + (value != undefined ? value : '')
  151.                                                         + '">');
  152.                                 } else if (col.expander) {
  153.                                         cc.push('<span class="datagrid-row-expander datagrid-row-expand" style="display:inline-block;width:25px;height:auto;cursor:pointer;" />');
  154.                                 } else if (col.formatter) {
  155.                                         cc.push(col.formatter(value, rowData, rowIndex));
  156.                                 } else {
  157.                                         cc.push(value);
  158.                                 }

  159.                                 cc.push('</div>');
  160.                                 cc.push('</td>');
  161.                         }
  162.                 }
  163.                 return cc.join('');
  164.         },

  165.         bindEvents : function(target) {
  166.                 var state = $.data(target, 'datagrid');
  167.                 var dc = state.dc;
  168.                 var opts = state.options;
  169.                 var body = dc.body1.add(dc.body2);
  170.                 var clickHandler = ($.data(body[0], 'events') || $._data(body[0],
  171.                                 'events')).click[0].handler;
  172.                 body.unbind('click').bind('click', function(e) {
  173.                                         var tt = $(e.target);
  174.                                         var tr = tt.closest('tr.datagrid-row');
  175.                                         if (!tr.length) {
  176.                                                 return
  177.                                         }
  178.                                         if (tt.hasClass('datagrid-row-expander')) {
  179.                                                 var rowIndex = parseInt(tr.attr('datagrid-row-index'));
  180.                                                 if (tt.hasClass('datagrid-row-expand')) {
  181.                                                         $(target).datagrid('expandRow', rowIndex);
  182.                                                 } else {
  183.                                                         $(target).datagrid('collapseRow', rowIndex);
  184.                                                 }
  185.                                                 $(target).datagrid('fixRowHeight');

  186.                                         } else {
  187.                                                 clickHandler(e);
  188.                                         }
  189.                                         e.stopPropagation();
  190.                                 });
  191.         },

  192.         onBeforeRender : function(target) {
  193.                 var state = $.data(target, 'datagrid');
  194.                 var opts = state.options;
  195.                 //这个是用来限制显示行数的
  196.                 var dc = state.dc;
  197.                 var view = this;
  198.                 /**
  199.                  * 设置行高,这个地方需要注意,如果不同行高,比如有图片或者其他的东西,请在rowStyle设置行高
  200.                  * 不然无法计算高度,并且调用rowStyler方法传入职为null这个需要注意下
  201.                  * 解析方法就是下面的,所以请不要添加空格什么的
  202.                  */
  203.                 opts.rowHeight = calculateDataGridTrStyleHeight(opts.rowStyler
  204.                                 ? opts.rowStyler.call(null, null, null)
  205.                                 : '');
  206.                 /**
  207.                  * 设置页行数,感觉每次滚动的条数在4行的样子,所以多渲染6行,chrome几乎没有感觉,ieie基本也没有啥感觉,
  208.                  * 这个+10可以自己调整下
  209.                  */
  210.                 opts.viewPageSize = Math.floor(dc.body2.height()/opts.rowHeight)+10;
  211.                 //这里用来缓存数据
  212.                 state.data.cacheRows  = state.data.rows;
  213.                 opts.finder.getRow = function(t, p) {
  214.                         var index = (typeof p == 'object')
  215.                                         ? p.attr('datagrid-row-index')
  216.                                         : p;
  217.                         var row = $.data(t, 'datagrid').data.rows[index];
  218.                         if (!row) {
  219.                                 var v = $(t).datagrid('options').view;
  220.                                 row = v.rows[index - v.index];
  221.                         }
  222.                         return row;
  223.                 };

  224.                 dc.body1.add(dc.body2).empty();
  225.                 this.rows = undefined; // the rows to be rendered
  226.                 this.r1 = this.r2 = []; // the first part and last part of rows

  227.                 init();
  228.                 createHeaderExpander();

  229.                 function init() {
  230.                         state.onLoadSuccess = opts.onLoadSuccess;
  231.                         opts.onLoadSuccess = function() {
  232.                         };
  233.                         setTimeout(function() {
  234.                                                 dc.body2.unbind('.datagrid').bind('scroll.datagrid',
  235.                                                                 function(e) {
  236.                                                                         if (state.onLoadSuccess) {
  237.                                                                                 opts.onLoadSuccess = state.onLoadSuccess; // restore
  238.                                                                                 state.onLoadSuccess = undefined;
  239.                                                                         }
  240.                                                                         if (view.scrollTimer) {
  241.                                                                                 clearTimeout(view.scrollTimer);
  242.                                                                         }
  243.                                                                         view.scrollTimer = setTimeout(function() {
  244.                                                                                                 scrolling.call(view);
  245.                                                                                         }, 50);
  246.                                                                 });
  247.                                                 dc.body2.triggerHandler('scroll.datagrid');
  248.                                         }, 0);
  249.                 }
  250.                 /**
  251.                  * 这里才是重点,监听滚动条的移动
  252.                  * 动态渲染行
  253.                  */
  254.                 function scrolling() {
  255.                         if (dc.body2.is(':empty')) {
  256.                                 reload.call(this);
  257.                         } else {
  258.                                 var firstTr = opts.finder.getTr(target, this.index, 'body', 2);
  259.                                 var lastTr = opts.finder.getTr(target, 0, 'last', 2);
  260.                                 var headerHeight = dc.view2.children('div.datagrid-header')
  261.                                                 .outerHeight();
  262.                                 var top = firstTr.position().top - headerHeight;
  263.                                 var bottom = lastTr.position().top + lastTr.outerHeight()
  264.                                                 - headerHeight;

  265.                                 if (top > dc.body2.height() || bottom < 0) {
  266.                                         reload.call(this);
  267.                                 } else if (top > 0) {
  268.                                         var page = Math.floor(this.index / opts.viewPageSize);
  269.                                         this.getRows.call(this, target, page, function(rows) {
  270.                                                                 this.r2 = this.r1;
  271.                                                                 this.r1 = rows;
  272.                                                                 this.index = (page - 1) * opts.viewPageSize;
  273.                                                                 this.rows = this.r1.concat(this.r2);
  274.                                                                 this.populate.call(this, target);
  275.                                                         });
  276.                                 } else if (bottom < dc.body2.height()) {
  277.                                         var page = Math.floor(this.index / opts.viewPageSize) + 2;
  278.                                         if (this.r2.length) {
  279.                                                 page++;
  280.                                         }
  281.                                         this.getRows.call(this, target, page, function(rows) {
  282.                                                                 if (!this.r2.length) {
  283.                                                                         this.r2 = rows;
  284.                                                                 } else {
  285.                                                                         this.r1 = this.r2;
  286.                                                                         this.r2 = rows;
  287.                                                                         this.index += opts.viewPageSize;
  288.                                                                 }
  289.                                                                 this.rows = this.r1.concat(this.r2);
  290.                                                                 this.populate.call(this, target);
  291.                                                         });
  292.                                 }
  293.                         }
  294.                         /**
  295.                          * 这里进行数据重载
  296.                          */
  297.                         function reload() {
  298.                                 var top = $(dc.body2).scrollTop();
  299.                                 var index = Math.floor(top / opts.rowHeight);
  300.                                 var page = Math.floor(index / opts.viewPageSize) + 1;

  301.                                 this.getRows.call(this, target, page, function(rows) {
  302.                                                         this.index = (page - 1) * opts.viewPageSize;
  303.                                                         this.rows = rows;
  304.                                                         this.r1 = rows;
  305.                                                         this.r2 = [];
  306.                                                         this.populate.call(this, target);
  307.                                                         dc.body2.triggerHandler('scroll.datagrid');
  308.                                                 });
  309.                         }
  310.                 }
  311.                 function createHeaderExpander() {
  312.                         if (!opts.detailFormatter) {
  313.                                 return
  314.                         }

  315.                         var t = $(target);
  316.                         var hasExpander = false;
  317.                         var fields = t.datagrid('getColumnFields', true).concat(t
  318.                                         .datagrid('getColumnFields'));
  319.                         for (var i = 0; i < fields.length; i++) {
  320.                                 var col = t.datagrid('getColumnOption', fields[i]);
  321.                                 if (col.expander) {
  322.                                         hasExpander = true;
  323.                                         break;
  324.                                 }
  325.                         }
  326.                         if (!hasExpander) {
  327.                                 if (opts.frozenColumns && opts.frozenColumns.length) {
  328.                                         opts.frozenColumns[0].splice(0, 0, {
  329.                                                                 field : '_expander',
  330.                                                                 expander : true,
  331.                                                                 width : 24,
  332.                                                                 resizable : false,
  333.                                                                 fixed : true
  334.                                                         });
  335.                                 } else {
  336.                                         opts.frozenColumns = [[{
  337.                                                                 field : '_expander',
  338.                                                                 expander : true,
  339.                                                                 width : 24,
  340.                                                                 resizable : false,
  341.                                                                 fixed : true
  342.                                                         }]];
  343.                                 }

  344.                                 var t = dc.view1.children('div.datagrid-header').find('table');
  345.                                 var td = $('<td rowspan="'
  346.                                                 + opts.frozenColumns.length
  347.                                                 + '"><div class="datagrid-header-expander" style="width:24px;"></div></td>');
  348.                                 if ($('tr', t).length == 0) {
  349.                                         td.wrap('<tr></tr>').parent().appendTo($('tbody', t));
  350.                                 } else if (opts.rownumbers) {
  351.                                         td.insertAfter(t
  352.                                                         .find('td:has(div.datagrid-header-rownumber)'));
  353.                                 } else {
  354.                                         td.prependTo(t.find('tr:first'));
  355.                                 }
  356.                         }

  357.                         setTimeout(function() {
  358.                                                 view.bindEvents(target);
  359.                                         }, 0);
  360.                 }
  361.         },

  362.         onAfterRender : function(target) {
  363.                 $.fn.datagrid.defaults.view.onAfterRender.call(this, target);
  364.                 var dc = $.data(target, 'datagrid').dc;
  365.                 var footer = dc.footer1.add(dc.footer2);
  366.                 footer.find('span.datagrid-row-expander').css('visibility', 'hidden');
  367.         },
  368.         /**
  369.          * getRows 获取数据的地方
  370.          * @param {} target
  371.          * @param {} page
  372.          * @param {} callback
  373.          */
  374.         getRows : function(target, page, callback) {
  375.                 var state = $.data(target, 'datagrid');
  376.                 var opts = state.options;
  377.                 var index = (page - 1) * opts.viewPageSize;
  378.                 var rows = state.data.cacheRows.slice(index, index + opts.viewPageSize);
  379.                 if (rows.length) {
  380.                         callback.call(this, rows);
  381.                 }
  382.         },

  383.         populate : function(target) {
  384.                 var state = $.data(target, 'datagrid');
  385.                 var opts = state.options;
  386.                 var dc = state.dc;
  387.                 var rowHeight = opts.rowHeight;

  388.                 if (this.rows.length) {
  389.                         opts.view.render.call(opts.view, target, dc.body2, false);
  390.                         opts.view.render.call(opts.view, target, dc.body1, true);
  391.                         dc.body1.add(dc.body2).children('table.datagrid-btable').css({
  392.                                 marginTop : this.index * rowHeight,
  393.                                 marginBottom : state.data.cacheRows.length * rowHeight - this.rows.length
  394.                                                 * rowHeight - this.index * rowHeight
  395.                         });
  396.                 }
  397.                 if (this.rows.length) {

  398.                         var r = [];
  399.                         for (var i = 0; i < this.index; i++) {
  400.                                 r.push({});
  401.                         }
  402.                         state.data.rows = r.concat(this.rows);
  403.                         /**
  404.                          * 这里是设置rows的条数,这个因为分页的,所以设置和当前页页相同
  405.                          */
  406.                         opts.onLoadSuccess.call(target, {
  407.                                                 total : this.rows.length,
  408.                                                 rows : this.rows
  409.                                         });
  410.                 }
  411.         }
  412. });

  413. $.extend($.fn.datagrid.methods, {       
  414.                         fixDetailRowHeight : function(jq, index) {
  415.                                 return jq.each(function() {
  416.                                                         var opts = $.data(this, 'datagrid').options;
  417.                                                         var dc = $.data(this, 'datagrid').dc;
  418.                                                         var tr1 = opts.finder.getTr(this, index, 'body', 1)
  419.                                                                         .next();
  420.                                                         var tr2 = opts.finder.getTr(this, index, 'body', 2)
  421.                                                                         .next();
  422.                                                         if (tr2.is(':visible')) {
  423.                                                                 tr1.css('height', '');
  424.                                                                 tr2.css('height', '');
  425.                                                                 var height = Math.max(tr1.height(), tr2
  426.                                                                                                 .height());
  427.                                                                 tr1.css('height', height);
  428.                                                                 tr2.css('height', height);
  429.                                                         }
  430.                                                         dc.body2.triggerHandler('scroll');
  431.                                                 });
  432.                         },
  433.                         getExpander : function(jq, index) { // get row expander object
  434.                                 var opts = $.data(jq[0], 'datagrid').options;
  435.                                 return opts.finder.getTr(jq[0], index)
  436.                                                 .find('span.datagrid-row-expander');
  437.                         },
  438.                         // get row detail container
  439.                         getRowDetail : function(jq, index) {
  440.                                 var opts = $.data(jq[0], 'datagrid').options;
  441.                                 var tr = opts.finder.getTr(jq[0], index, 'body', 2);
  442.                                 return tr.next().find('div.datagrid-row-detail');
  443.                         },
  444.                         expandRow : function(jq, index) {
  445.                                 return jq.each(function() {
  446.                                                         var opts = $(this).datagrid('options');
  447.                                                         var dc = $.data(this, 'datagrid').dc;
  448.                                                         var expander = $(this).datagrid('getExpander',
  449.                                                                         index);
  450.                                                         if (expander.hasClass('datagrid-row-expand')) {
  451.                                                                 expander.removeClass('datagrid-row-expand')
  452.                                                                                 .addClass('datagrid-row-collapse');
  453.                                                                 var tr1 = opts.finder.getTr(this, index,
  454.                                                                                 'body', 1).next();
  455.                                                                 var tr2 = opts.finder.getTr(this, index,
  456.                                                                                 'body', 2).next();
  457.                                                                 tr1.show();
  458.                                                                 tr2.show();
  459.                                                                 $(this).datagrid('fixDetailRowHeight', index);
  460.                                                                 if (opts.onExpandRow) {
  461.                                                                         var row = $(this).datagrid('getRows')[index];
  462.                                                                         opts.onExpandRow.call(this, index, row);
  463.                                                                 }
  464.                                                         }
  465.                                                 });
  466.                         },
  467.                         collapseRow : function(jq, index) {
  468.                                 return jq.each(function() {
  469.                                                         var opts = $(this).datagrid('options');
  470.                                                         var dc = $.data(this, 'datagrid').dc;
  471.                                                         var expander = $(this).datagrid('getExpander',
  472.                                                                         index);
  473.                                                         if (expander.hasClass('datagrid-row-collapse')) {
  474.                                                                 expander.removeClass('datagrid-row-collapse')
  475.                                                                                 .addClass('datagrid-row-expand');
  476.                                                                 var tr1 = opts.finder.getTr(this, index,
  477.                                                                                 'body', 1).next();
  478.                                                                 var tr2 = opts.finder.getTr(this, index,
  479.                                                                                 'body', 2).next();
  480.                                                                 tr1.hide();
  481.                                                                 tr2.hide();
  482.                                                                 dc.body2.triggerHandler('scroll');
  483.                                                                 if (opts.onCollapseRow) {
  484.                                                                         var row = $(this).datagrid('getRows')[index];
  485.                                                                         opts.onCollapseRow.call(this, index, row);
  486.                                                                 }
  487.                                                         }
  488.                                                 });
  489.                         }
  490.                 });
  491. function calculateDataGridTrStyleHeight(css) {
  492.         var styleValue;
  493.         if (typeof css == 'string') {
  494.                 styleValue = css;
  495.         } else if (css) {
  496.                 classValue = css['class'] || '';
  497.                 styleValue = css['style'] || '';
  498.         }

  499.         if (styleValue && styleValue.indexOf("height") > -1) {
  500.                 var index = styleValue.indexOf("height") + 7;
  501.                 styleValue = styleValue.substr(index);
  502.                 return styleValue.substring(0, styleValue.indexOf(";"))
  503.                                 .replace("px", '');
  504.         }
  505.         return 25;

  506. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表