栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

jQuery EasyUI框架中的Datagrid数据表格组件结构详解

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

jQuery EasyUI框架中的Datagrid数据表格组件结构详解

基础DOM结构
什么叫“完整的基础DOM结构”,这里“基础”的意思是指这个结构不依赖具体数据,不依赖Datagrid的view属性,只要存在Datagrid实例就会存在这样的基础DOM结构;而“完整”的意思是指在冻结列,冻结行,标题,footer,分页这些功能块都存在时候的DOM结构。

要搞清楚Datagrid的工作原理,这个DOM结构必须要烂熟于胸的,我们直接来看这个“基础完整DOM结构”是什么样子的:

   
   
     
     


     
     
   
     

       
       

         
         
  
    
    
      
      
        
     

对于这个DOM结构,我在html代码里面已经做了简单说明,这里提一下绑定于Datagrid宿主table上的对象的dc属性,这个dc属性存储了对DOM结构里不同部分的引用,获取dc属性的方法:

$.data(target,'datagrid').dc;

而dc属性跟DOM的对应关系,我也在html中做了详细注释,请大家自行查看,这些都是我们深入认识Datagrid组件的基础。

默认视图分析
上面对Datagrid组件的骨架做了很详细的描述。有了骨架还并不完整,还得有血有肉有衣服穿才行。强大的Datagrid组件允许我们自己定义如何在基础骨架上长出健壮诱人的身体,我们只要定义Datagrid的视图就可以实现。

在大多数情况下,我们并无特别要求,Datagrid给我们提供了默认的视图,默认视图被使用在90%以上的场景,所以对默认视图的分析显得非常有必要。注意视图里面定义了哪些接口,哪些方法,如果要自己写视图的话,最好把这些接口和方法都写齐全。

var view = {  
   
  render: function(target, container, frozen) {  
    var data = $.data(target, "datagrid");  
    var opts = data.options;  
    var rows = data.data.rows;  
    var fields = $(target).datagrid("getColumnFields", frozen);  
    if(frozen) {  
      //如果grid不显示rownumbers并且也没有frozenColumns的话,直接退出。  
      if(!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))) {  
 return;  
      }  
    }  
    //定义表格字符串,注意这里使用了数组的join方式代替了传统的"+"运算符,在大多浏览器中,这样效率会更高些。  
    var html = [""];  
    for(var i = 0; i < rows.length; i++) {  
      //striped属性,用于设置grid数据是否隔行变色,当然了实现原理很简单。  
      var cls = (i % 2 && opts.striped) ? "class="datagrid-row datagrid-row-alt"" : "class="datagrid-row"";  
       
      var style = opts.rowStyler ? opts.rowStyler.call(target, i, rows[i]) : "";  
      var styler = style ? "style="" + style + """ : "";  
       
      var rowId = data.rowIdPrefix + "-" + (frozen ? 1 : 2) + "-" + i;  
      html.push("");  
       
      html.push(this.renderRow.call(this, target, fields, frozen, i, rows[i]));  
      html.push("");  
    }  
    html.push("
"); //用join方法完成字符创拼接后直接innerHTML到容器内。 $(container).html(html.join("")); }, renderFooter: function(target, container, frozen) { var opts = $.data(target, "datagrid").options; //获取footer数据 var rows = $.data(target, "datagrid").footer || []; var columnsFields = $(target).datagrid("getColumnFields", frozen); //生成footer区的table var footerTable = [""]; for(var i = 0; i < rows.length; i++) { footerTable.push(""); footerTable.push(this.renderRow.call(this, target, columnsFields, frozen, i, rows[i])); footerTable.push(""); } footerTable.push("
"); $(container).html(footerTable.join("")); }, renderRow: function(target, fields, frozen, rowIndex, rowData) { var opts = $.data(target, "datagrid").options; //用于拼接字符串的数组 var cc = []; if(frozen && opts.rownumbers) { //rowIndex从0开始,而行号显示的时候是从1开始,所以这里要加1. var rowNumber = rowIndex + 1; //如果分页的话,根据页码和每页记录数重新设置行号 if(opts.pagination) { rowNumber += (opts.pageNumber - 1) * opts.pageSize; } cc.push("" + rowNumber + ""); } for(var i = 0; i < fields.length; i++) { var field = fields[i]; var col = $(target).datagrid("getColumnOption", field); if(col) { var value = rowData[field]; //获取用户定义的单元格样式,入参包括:单元格值,当前行数据,当前行索引(从0开始) var style = col.styler ? (col.styler(value, rowData, rowIndex) || "") : ""; //如果是隐藏列直接设置display为none,否则设置为用户想要的样式 var styler = col.hidden ? "style="display:none;" + style + """ : (style ? "style="" + style + """ : ""); cc.push(""); //如果当前列是datagrid组件保留的ck列时,则忽略掉用户定义的样式,即styler属性对datagrid自带的ck列是不起作用的。 if(col.checkbox) { var styler = ""; } else { var styler = ""; //设置文字对齐属性 if(col.align) { styler += "text-align:" + col.align + ";"; } //设置文字超出td宽时是否自动换行(设置为自动换行的话会撑高单元格) if(!opts.nowrap) { styler += "white-space:normal;height:auto;"; } else { if(opts.autoRowHeight) { styler += "height:auto;"; } } } //这个地方要特别注意,前面所拼接的styler属性并不是作用于td标签上,而是作用于td下的div标签上。 cc.push(""); if(col.checkbox) { cc.push(""); } //普通列 else { if(col.formatter) { cc.push(col.formatter(value, rowData, rowIndex)); } //操,这是最简单的简况了,将值直接放到td>div里面。 else { cc.push(value); } } cc.push(""); cc.push(""); } } //返回单元格字符串,注意这个函数内部并未把字符串放到文档流中。 return cc.join(""); }, refreshRow: function(target, rowIndex) { this.updateRow.call(this, target, rowIndex, {}); }, updateRow: function(target, rowIndex, row) { var opts = $.data(target, "datagrid").options; var rows = $(target).datagrid("getRows"); $.extend(rows[rowIndex], row); var style = opts.rowStyler ? opts.rowStyler.call(target, rowIndex, rows[rowIndex]) : ""; function updateTableRow(frozen) { var fields = $(target).datagrid("getColumnFields", frozen); //这个地方查找grid的数据主体表格(可能包含冻结列对应的主体表格和普通列对应的主体表格) //getTr这个函数,我在博客上介绍过,请参考:http://www.easyui.info/archives/396.html var tr = opts.finder.getTr(target, rowIndex, "body", (frozen ? 1 : 2)); var checked = tr.find("div.datagrid-cell-check input[type=checkbox]").is(":checked"); //这里调用了renderRow方法来重新获取当前行的html字符串 tr.html(this.renderRow.call(this, target, fields, frozen, rowIndex, rows[rowIndex])); tr.attr("style", style || ""); //更新的时候保留checkbox状态(包含两层信息:一是有ck列;二是ck列被之前就被选中) if(checked) { tr.find("div.datagrid-cell-check input[type=checkbox]")._propAttr("checked", true); } }; //更新冻结列对应的行 updateTableRow.call(this, true); //更新普通列对应的行 updateTableRow.call(this, false); //重新布局表格面板 $(target).datagrid("fixRowHeight", rowIndex); }, insertRow: function(target, rowIndex, row) { var state = $.data(target, "datagrid"); //options var opts = state.options; //document of datagrid var dc = state.dc; var data = state.data; //兼容无效的rowIndex,默认设置为在最后一行追加 if(rowIndex == undefined || rowIndex == null) { rowIndex = data.rows.length; } //为啥不跟上面的条件并到一起,真是蛋疼 if(rowIndex > data.rows.length) { rowIndex = data.rows.length; } function moveDownRows(frozen) { //1:冻结列部分;2:普通列部分 var whichBody = frozen ? 1 : 2; for(var i = data.rows.length - 1; i >= rowIndex; i--) { var tr = opts.finder.getTr(target, i, "body", whichBody); //注意这地方设置了tr的"datagrid-row-index"和"id"属性 tr.attr("datagrid-row-index", i + 1); tr.attr("id", state.rowIdPrefix + "-" + whichBody + "-" + (i + 1)); //计算行号 if(frozen && opts.rownumbers) { //因rowIndex从0开始,以及须插入位置以下的tr要统一下移,所以新行号为i+2 var rownumber = i + 2; //有分页的话,行号还要加上分页数据 if(opts.pagination) { rownumber += (opts.pageNumber - 1) * opts.pageSize; } tr.find("div.datagrid-cell-rownumber").html(rownumber); } } }; function doInsert(frozen) { var whichBody = frozen ? 1 : 2; //这行代码,不知道是干嘛的,怕插入得太快而早早缴械,所以才故意拖延时间的么? var columnFields = $(target).datagrid("getColumnFields", frozen); //构造新插入行的id属性 var trId = state.rowIdPrefix + "-" + whichBody + "-" + rowIndex; var tr = ""; if(rowIndex >= data.rows.length) { //如果已经有记录,则插入tr即可 if(data.rows.length) { //嗯哼,getTr的这个用法不多哦,未传入行索引,第三个参数为"last",随便的意淫一下就知道是获取最后一行了 //然后再在最后一行后插入一行,注意了,这里用的后入式 opts.finder.getTr(target, "", "last", whichBody).after(tr); } //如果表格尚无记录,则要生成表格,同时插入tr else { var cc = frozen ? dc.body1 : dc.body2; cc.html("" + tr + "
"); } } //在rowIndex + 1前准确无误地插入,注意了,这里是前入式。 else { opts.finder.getTr(target, rowIndex + 1, "body", whichBody).before(tr); } }; //下移frozen部分 moveDownRows.call(this, true); //下移普通列部分 moveDownRows.call(this, false); //插入frozen区 doInsert.call(this, true); //插入普通区 doInsert.call(this, false); //总数加1 data.total += 1; //维护data.rows数组,这地方是插入一个数组元素了 data.rows.splice(rowIndex, 0, row); //刷新,其中包含了重新布局grid面板等复杂得一笔的操作 //插入本是件很简单愉快的事情,可是你得为其后果负上沉重的代价 this.refreshRow.call(this, target, rowIndex); }, deleteRow: function(target, rowIndex) { var state = $.data(target, "datagrid"); var opts = state.options; var data = state.data; function moveUpRows(frozen) { var whichBody = frozen ? 1 : 2; for(var i = rowIndex + 1; i < data.rows.length; i++) { var tr = opts.finder.getTr(target, i, "body", whichBody); //"datagrid-row-index"和"id"属性减一 tr.attr("datagrid-row-index", i - 1); tr.attr("id", state.rowIdPrefix + "-" + whichBody + "-" + (i - 1)); if(frozen && opts.rownumbers) { var rownumber = i; if(opts.pagination) { rownumber += (opts.pageNumber - 1) * opts.pageSize; } tr.find("div.datagrid-cell-rownumber").html(rownumber); } } }; //移除行 opts.finder.getTr(target, rowIndex).remove(); //上移frozen区 moveUpRows.call(this, true); //上移普通区 moveUpRows.call(this, false); //记录数减一 data.total -= 1; //维护data.rows数据 data.rows.splice(rowIndex, 1); }, onBeforeRender: function(target, rows) {}, onAfterRender: function(target) { var opts = $.data(target, "datagrid").options; if(opts.showFooter) { var footer = $(target).datagrid("getPanel").find("div.datagrid-footer"); footer.find("div.datagrid-cell-rownumber,div.datagrid-cell-check").css("visibility", "hidden"); } } };

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/96298.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号