当前位置: 首页 > 编程日记 > 正文

JqGridView 1.0.0.0发布

前几个月,客户要求显示列表做到列锁定+表头锁定+列组合,但从Extjs到Jquery EasyUi,从Jquery Grid到Telerik等等组件,发现无一符合条件,要么只能用列锁定,要么只能用列组合,当两者结合就不行了。于是只好开始自己琢磨了,然后就有了jqGridView。

设计思路

在开始之前,总得理下思路。我CSS不行,JS一般,但是我有思路,先看看下面两个图:

imagez

image

从上图中可以看出,毫无疑问的,我们需要将一个列表切成4块——锁定列表头、锁定列数据行、非锁定列表头、非锁定列数据行。如图:

image

其中,锁定列表头、锁定列数据列、非锁定列表头均无滚动条,滚动条全在非锁定列数据列,但拖动右侧滚动条,需要联动锁定列数据行,但拖动底部滚动条,需联动非锁定列表头。

在我认为,磨刀不误砍柴工。好的想法、好的设计才能更大可能性的走向成功。

接下来,是细节的实现了:

选择什么编程语言呢?好像还没写过Jquery插件,那么就用这个来练练手吧。我对开发新东西或者实现自己的想法或者有兴趣却不熟悉的编码特别来劲。

选择什么方式呢?开始,毫无意外的想到使用Table来组合,于是坑次坑次的开始了。当编码完成后,发现一个棘手的问题——模块之间无法对齐。即使设置了每个单元格宽度以及表格宽度也不行,请了美工辅助也不行,于是放弃了。有意向的朋友可以试试。table不行,那就试试Div吧,人总不能在一条路上走死吧。于是又坑次坑次的开始了,终于修改N次后完成了。

样例

首先举几个例子来说明如何使用:

简单单行表头

    <script type="text/javascript">$(function() {$.jqGridView('<%=gvData.ClientID %>', {lockColumns: 3,isRemoveGridView: true,rowStyle: 'gv-tr-rowStyle',alternatingRowStyle: 'gv-tr-alternatingRowStyle',hoverRowStyle: 'gv-tr-hoverRowStyle'});});</script>

image

合并列

    <script type="text/javascript">$(function () {$.jqGridView('<%=gvData.ClientID %>', {lockColumns: 3,isRemoveGridView: true,rowStyle: 'gv-tr-rowStyle',alternatingRowStyle: 'gv-tr-alternatingRowStyle',hoverRowStyle: 'gv-tr-hoverRowStyle',leftGroupCols: '<tr><th rowspan="2" colspan="3">单位</th></tr>',rightGroupCols: '<tr><th scope="col" colspan="3" style="text-align:center">待定</th><th scope="col" colspan="3" style="text-align:center">1级</th><th scope="col" colspan="3" style="text-align:center">2级</th><th scope="col" colspan="3" style="text-align:center">3级</th><th scope="col" colspan="3" style="text-align:center">4级</th><th scope="col" colspan="3" style="text-align:center">5级</th><th scope="col" colspan="3" style="text-align:center">6级</th><th scope="col" colspan="3" style="text-align:center">7级</th><th scope="col" colspan="3" style="text-align:center">8级</th><th scope="col" colspan="3" style="text-align:center">9级</th><th scope="col" colspan="3" style="text-align:center">10级</th><th scope="col" colspan="3" style="text-align:center">11级</th><th scope="col" colspan="3" style="text-align:center">12级</th><th scope="col" colspan="3" style="text-align:center">13级</th><th scope="col" colspan="3" style="text-align:center">14级</th><th scope="col" colspan="3" style="text-align:center">15级</th><th scope="col" colspan="2" style="text-align:center">16级</th></tr>'});});</script>

image

行点击事件

    <script type="text/javascript">$(function () {$.jqGridView('<%=gvData.ClientID %>', {lockColumns: 3,isRemoveGridView: true,rowStyle: 'gv-tr-rowStyle',alternatingRowStyle: 'gv-tr-alternatingRowStyle',hoverRowStyle: 'gv-tr-hoverRowStyle',leftGroupCols: '<tr><th rowspan="2" colspan="3">单位</th></tr>',rightGroupCols: '<tr><th scope="col" colspan="3" style="text-align:center">待定</th><th scope="col" colspan="3" style="text-align:center">1级</th><th scope="col" colspan="3" style="text-align:center">2级</th><th scope="col" colspan="3" style="text-align:center">3级</th><th scope="col" colspan="3" style="text-align:center">4级</th><th scope="col" colspan="3" style="text-align:center">5级</th><th scope="col" colspan="3" style="text-align:center">6级</th><th scope="col" colspan="3" style="text-align:center">7级</th><th scope="col" colspan="3" style="text-align:center">8级</th><th scope="col" colspan="3" style="text-align:center">9级</th><th scope="col" colspan="3" style="text-align:center">10级</th><th scope="col" colspan="3" style="text-align:center">11级</th><th scope="col" colspan="3" style="text-align:center">12级</th><th scope="col" colspan="3" style="text-align:center">13级</th><th scope="col" colspan="3" style="text-align:center">14级</th><th scope="col" colspan="3" style="text-align:center">15级</th><th scope="col" colspan="2" style="text-align:center">16级</th></tr>',rowClick: function (e) {var tds = e.data.tds;var rowIndex = e.data.rIndex;var isLeft = e.data.isLeft;alert("列1行" + rowIndex + "的值为:" + tds.eq(0).text() + ",您点击的是" + (isLeft ? "锁定列" : "非锁定列"));}});});</script>

image

image

样式

既然决定使用div,那么样式少不了。我倾向于外观方面的控制全放在样式里面,于是定义了以下样式:

jqGridView样式/*jqGridView Style */
.gv-dataContent
{width: 750px;height: 320px;margin: 5px auto;text-align:left;
}.gv-dataContent th, tr
{white-space: nowrap;
}
.gv-dataContent td, th
{padding: 0 0 0 0;margin: 0 0 0 0;white-space: nowrap;
}
.gv-header-left
{width: auto;overflow: hidden;float: left;border-left: 1px solid #539ebb;border-collapse: collapse;
}
.gv-header-right
{overflow: hidden;border-collapse: collapse;
}
.gv-data-left
{width: auto;overflow: hidden;float: left;border-left: 1px solid #539ebb;border-bottom: 1px solid #539ebb;border-collapse: collapse;
}
.gv-data-right
{overflow: scroll;border-collapse: collapse;
}
.gv-div-table
{border-collapse: collapse;width: auto;
}
.gv-div-tr
{clear: both;height: 30px;overflow: hidden;
}
.gv-div-th, .gv-div-td
{height: 30px;float: left;border: 1px solid white;margin: 0px 0 0 -1px;text-align: center;vertical-align: middle;line-height: 30px;border-collapse: collapse;float: left;color: #3274a4;
}
.gv-div-th
{background-color: #86A9D2;font-weight: bold;border: 1px solid white;
}
.gv-tr-rowStyle
{background-color: #8ecbe3;
}
.gv-tr-alternatingRowStyle
{background-color: #d3ebf4;
}
.gv-tr-hoverRowStyle
{background-color: #6786d6;cursor:pointer;
}
/*GridView 样式*/
.HeaderStyle
{background-color:#86A9D2;font-weight:bold;height:26px;white-space: nowrap;text-align:center;border: 1px solid white;color: #3274a4;
}
.RowStyle
{background-color: #8ecbe3;height:26px;text-align:center;white-space: nowrap;border: 1px solid white;color: #3274a4;
}
.AlternatingRowStyle
{background-color: #d3ebf4;height:26px;white-space: nowrap;border: 1px solid white;color: #3274a4;text-align: center;
}
.datacontent
{	font-size:12px;font-family:微软雅黑;width:740px;border:1px solid #7C9BBF; margin:0 auto;clear: both; text-align: center; 	*text-align: center; margin-left: 5px;padding:5px;width:760px;overflow:auto;}

从样式中可以看出大体的规则,也是仿照table元素来的。table、tr、th、td等等。其中有几个重要样式要注意了:

  1. .gv-dataContent    整个jqGridView的整体样式
  2. .gv-header-left      左侧表头区域
  3. .gv-header-right    右侧表头区域
  4. .gv-data-left    左侧数据区域
  5. .gv-data-right  右侧数据区域
  6. .gv-div-table   表示一个表格,每个区域均存在
  7. .gv-div-tr    表示行样式
  8. .gv-div-th   表示表头单元格样式
  9. .gv-div-td   表示单元格样式
  10. .gv-tr-rowStyle   表示奇数行样式
  11. .gv-tr-alternatingRowStyle   表示偶数行样式
  12. .gv-tr-hoverRowStyle  表示悬浮行样式

编码

先贴上代码:

   1: /**
   2: * 本插件用于实现GridView的列锁定和表头锁定,以及表头组合
   3: * @example  $.jqGridView('<%=gvData.ClientID %>', { lockColumns: 3 });
   4: * @param String gridViewClientID GridView的客户端ID
   5: * @option Number lockColumns 锁定的列数。如果包含合并表头,请与合并表头的列数一致。
   6: * @option String leftGroupCols 左侧合并列的HTML,不设置则默认为单行表头。
   7: * @option String rightGroupCols 右侧合并列的HTML,不设置则默认为单行表头。
   8: * @option String removeLeftHeaderStrBySplit 根据分隔符移除左侧头部字符。
   9: * @option String removeRightHeaderStrBySplit 根据分隔符移除右侧头部字符。
  10: * @option String rowStyle 偶数行样式。
  11: * @option String alternatingRowStyle 奇数行样式。
  12: * @option String hoverRowStyle 悬浮行样式。
  13: * @option Bool isRemoveEmptyAndZeroCols 是否移除空列或者0列。
  14: * @option Bool isHideGridView 是否在处理后隐藏GridView。
  15: * @option Bool isRemoveGridView 是否在处理后移除GridView。
  16: * @option String emptyMessage 没有数据时显示的内容,默认为“没有数据。”。
  17: * @option event rowClick 行单击事件。
  18: * @author 雪雁 
  19: * @email codelove1314@foxmail.com    
  20: * @webSite http://www.cnblogs.com/codelove/  
  21: */
  22: jQuery.jqGridView = function (gridViewClientID, options) {
  23:     if (gridViewClientID !== undefined && options !== undefined) {
  24:         function formatHeaderHtml(html) {
  25:             return html.replace(/\<tr/g, '<div class="gv-div-tr" ').replace(/<\/tr>/g, '</div>')
  26:             .replace(/\<th/g, '<div class="gv-div-th" ').replace(/<\/th>/g, '</div>')
  27:             .replace(/\<td/g, '<div class="gv-div-th" ').replace(/<\/td>/g, '</div>');
  28:         }
  29:         //锁定的列数
  30:         var lockColumns = options.lockColumns === undefined ? 1 : options.lockColumns;
  31:         //左侧组合列HTML
  32:         var leftGroupCols = $(options.leftGroupCols === undefined ? '' : formatHeaderHtml(options.leftGroupCols));
  33:         //右侧组合列HTML
  34:         var rightGroupCols = $(options.rightGroupCols === undefined ? '' : formatHeaderHtml(options.rightGroupCols));
  35:         //根据分隔符移除左侧头部字符
  36:         var removeLeftHeaderStrBySplit = options.removeLeftHeaderStrBySplit === undefined ? '' : options.removeLeftHeaderStrBySplit;
  37:         var removeRightHeaderStrBySplit = options.removeRightHeaderStrBySplit === undefined ? '' : options.removeRightHeaderStrBySplit;
  38:         //偶数行样式
  39:         var rowStyle = options.rowStyle === undefined ? '' : options.rowStyle;
  40:         //奇数行样式
  41:         var alternatingRowStyle = options.alternatingRowStyle === undefined ? '' : options.alternatingRowStyle;
  42:         //鼠标悬浮行样式
  43:         var hoverRowStyle = options.hoverRowStyle === undefined ? '' : options.hoverRowStyle;
  44:         var isSafari = $.browser.safari;
  45:         //数据空显示内容
  46:         var emptyMessage = options.emptyMessage === undefined ? '没有数据。' : options.emptyMessage;
  47:         var gvData = $('#' + gridViewClientID);
  48:         if (!gvData || gvData.length == 0) {
  49:             console.error("GridView不存在,请检查!!!", gridViewClientID, options);
  50:             return;
  51:         }
  52:         //是否移除空列或者0列
  53:         if (options.isRemoveEmptyAndZeroCols !== undefined && options.isRemoveEmptyAndZeroCols) {
  54:             var arr_remove = new Array(gvData.find('tr:eq(0) th').length);
  55:             var rowsCount = gvData.find('tr:gt(0)').each(function (rIndex) {
  56:                 var tr = $(this);
  57:                 tr.find('td').each(function (cIndex) {
  58:                     if (arr_remove[cIndex] === undefined || arr_remove[cIndex] == null)
  59:                         arr_remove[cIndex] = 0;
  60:                     var val = $(this).text().replace(/(^\s*)|(\s*$)/g, "");
  61:                     if (val == '' || val == 0) {
  62:                         arr_remove[cIndex]++;
  63:                     }
  64:                 });
  65:             }).length;
  66:             gvData.find('tr').each(function (rIndex) {
  67:                 var tr = $(this);
  68:                 tr.find('td,th').each(function (cIndex) {
  69:                     if (arr_remove[cIndex] == rowsCount)
  70:                         $(this).remove();
  71:                 });
  72:             });
  73:         }
  74:         var leftCols = lockColumns - 1;
  75:         var rightCols = lockColumns;
  76:         var isRemoveGridView = options.isRemoveGridView === undefined ? true : options.isRemoveGridView;
  77:         //所有列宽
  78:         var colsLengsArr = new Array();
  79:         var colsCount = gvData.find('tr:eq(0) th').each(function (i) {
  80:             colsLengsArr[i] = ($(this).outerWidth() + 1);
  81:         }).length;
  82:         if (lockColumns >= colsCount) lockColumns = colsCount;
  83:         //左侧table宽度
  84:         var leftTableWidth = 1;
  85:         //右侧table宽度
  86:         var rightTableWidth = 1;
  87:         for (var i = 0; i < lockColumns; i++) {
  88:             leftTableWidth += (colsLengsArr[i] + 1);
  89:             if (isSafari) leftTableWidth += 0.3;
  90:         }
  91:         for (var i = lockColumns; i < colsLengsArr.length; i++) {
  92:             rightTableWidth += (colsLengsArr[i] + 1);
  93:             if (isSafari) rightTableWidth += 0.3;
  94:         }
  95:  
  96:         gvData.parent().prepend('<div class="gv-dataContent"></div>');
  97:         var gv_dataContent = $('.gv-dataContent');
  98:         if (gvData.find('tr').length <= 1) {
  99:             gv_dataContent.prepend('<div class="gv-empty">' + emptyMessage + '</div>');
 100:             return;
 101:         }
 102:         //右侧区域宽度
 103:         var rightAreaWidth = gv_dataContent.width() - (leftTableWidth + 25);
 104:         //数据区域高度
 105:         var dataAreaHeight = gv_dataContent.height();
 106:  
 107:         gv_dataContent.prepend('<div class="gv-header-left"></div><div class="gv-header-right"></div><div class="gv-data-left"></div><div class="gv-data-right"></div>');
 108:         var gv_header_left = gv_dataContent.find('div.gv-header-left');
 109:         var gv_header_right = gv_dataContent.find('div.gv-header-right');
 110:         var gv_data_left = gv_dataContent.find('div.gv-data-left');
 111:         var gv_data_right = gv_dataContent.find('div.gv-data-right');
 112:         if (lockColumns == colsCount) {
 113:             gv_header_right.hide(); gv_data_right.hide();
 114:         } else {
 115:             if (rightAreaWidth > 0) {
 116:                 gv_header_right.width(rightAreaWidth);
 117:                 gv_data_right.width(rightAreaWidth + 18);
 118:             }
 119:         }
 120:         var gvData_header_left = gvData.clone();
 121:         gvData_header_left.find('tr:gt(0)').remove();
 122:  
 123:         var gvData_header_right = gvData_header_left.clone();
 124:         gv_header_right.find('tr th').remove();
 125:  
 126:         gv_data_right.find('tr:eq(0)').prepend(gvData_header_left.find('th:gt(' + lockColumns + ')').clone());
 127:         gvData_header_right.find('th:lt(' + rightCols + ')').remove();
 128:         gvData_header_left.find('th:gt(' + leftCols + ')').remove();
 129:         var colIndex = 0;
 130:  
 131:         function setThs(jqTr, jqHeader, isLeft) {
 132:             //            var trHtml = '<div class="gv-div-table" style="width:' + (isLeft ? leftTableWidth : rightTableWidth) + 'px;"><div class="gv-div-tr">';
 133:             var trHtml = '<div class="gv-div-table" style="width:' + (isLeft ? 'auto' : (rightTableWidth + 'px;')) + '"><div class="gv-div-tr">';
 134:             jqTr.find('th').each(function (j) {
 135:                 trHtml += '<div class="gv-div-th" style="width:' + colsLengsArr[colIndex] + 'px;">';
 136:                 if (removeLeftHeaderStrBySplit != '') {
 137:                     var splitStrs = $(this).text().split(removeLeftHeaderStrBySplit);
 138:                     trHtml += splitStrs.length > 1 ? splitStrs[1] : splitStrs[0];
 139:                 } else if (removeRightHeaderStrBySplit != '') {
 140:                     var splitStrs = $(this).text().split(removeRightHeaderStrBySplit);
 141:                     trHtml += splitStrs[0];
 142:                 }
 143:                 else
 144:                     trHtml += $(this).html();
 145:                 trHtml += '</div>';
 146:                 colIndex++;
 147:             });
 148:             trHtml += '</div></div>';
 149:             jqHeader.prepend(trHtml);
 150:         }
 151:  
 152:         //设置左侧头部HTML
 153:         setThs(gvData_header_left, gv_header_left, true);
 154:         //设置右侧头部HTML
 155:         setThs(gvData_header_right, gv_header_right, false);
 156:         //        var gvData_Data_left = $('<div class="gv-div-table" style="width:' + leftTableWidth + 'px;"></div>');
 157:         var gvData_Data_left = $('<div class="gv-div-table" style="width:auto;"></div>');
 158:         var gvData_Data_right = $('<div class="gv-div-table" style="width:' + rightTableWidth + 'px;"></div>');
 159:         gvData.find("tr:gt(0)").each(function (i) {
 160:             var tr = $(this);
 161:             var trLeft = tr.clone();
 162:             var trRight = tr.clone();
 163:             trLeft.find('td:gt(' + leftCols + ')').remove();
 164:             trRight.find('td:lt(' + rightCols + ')').remove();
 165:             colIndex = 0;
 166:             function setTrTds(tr_left, gvData_Data_left, tr_right, gvData_Data_right, trInfo) {
 167:                 var trLeftHtml = '<div class="gv-div-tr';
 168:                 if (rowStyle != '' && i % 2 == 0)
 169:                     trLeftHtml += ' ' + rowStyle;
 170:                 else if (alternatingRowStyle != '' && i % 2 == 1)
 171:                     trLeftHtml += ' ' + alternatingRowStyle;
 172:                 trLeftHtml += '">';
 173:                 var trRightHtml = trLeftHtml;
 174:                 tr_left.find('td').each(function (j) {
 175:                     trLeftHtml += '<div class="gv-div-td" style="width:' + colsLengsArr[colIndex] + 'px;">' + $(this).html() + '</div>';
 176:                     colIndex++;
 177:                 });
 178:                 tr_right.find('td').each(function (j) {
 179:                     trRightHtml += '<div class="gv-div-td" style="width:' + colsLengsArr[colIndex] + 'px;">' + $(this).html() + '</div>';
 180:                     colIndex++;
 181:                 });
 182:                 trLeftHtml += '</div>'; trRightHtml += '</div>';
 183:                 var jqLeftTrHrml = $(trLeftHtml); var jqRightTrHrml = $(trRightHtml);
 184:                 if (options.rowClick !== undefined) {
 185:                     jqLeftTrHrml.bind('click', { tds: trInfo.find('td'), rIndex: i, isLeft: true }, options.rowClick);
 186:                     jqRightTrHrml.bind('click', { tds: trInfo.find('td'), rIndex: i, isLeft: false }, options.rowClick);
 187:                 }
 188:                 if (hoverRowStyle != '') {
 189:                     jqLeftTrHrml.hover(function () { jqLeftTrHrml.addClass(hoverRowStyle); jqRightTrHrml.addClass(hoverRowStyle); }, function () { jqLeftTrHrml.removeClass(hoverRowStyle); jqRightTrHrml.removeClass(hoverRowStyle); });
 190:                     jqRightTrHrml.hover(function () { jqLeftTrHrml.addClass(hoverRowStyle); jqRightTrHrml.addClass(hoverRowStyle); }, function () { jqLeftTrHrml.removeClass(hoverRowStyle); jqRightTrHrml.removeClass(hoverRowStyle); });
 191:                 }
 192:                 gvData_Data_left.append(jqLeftTrHrml);
 193:                 gvData_Data_right.append(jqRightTrHrml);
 194:             }
 195:             setTrTds(trLeft, gvData_Data_left, trRight, gvData_Data_right, tr);
 196:         });
 197:         gv_data_left.prepend(gvData_Data_left);
 198:         gv_data_right.prepend(gvData_Data_right);
 199:         if (options.isHideGridView !== undefined && options.isHideGridView)
 200:             gvData.hide();
 201:         if (isRemoveGridView)
 202:             gvData.remove();
 203:         if (leftGroupCols != '' && rightGroupCols != '') {
 204:             dataAreaHeight -= 62;
 205:             colIndex = 0;
 206:             function calcGroupCol(groupCols) {
 207:                 var groupThs = groupCols.find('.gv-div-th');
 208:                 groupThs.each(function (i) {
 209:                     var col_width = 0;
 210:                     if ($(this).attr('colspan') !== undefined) {
 211:                         var colSpan = parseInt($(this).attr('colspan'));
 212:                         for (var i = 0; i < colSpan; i++) {
 213:                             col_width += colsLengsArr[colIndex];
 214:                             colIndex++;
 215:                         }
 216:                         col_width += (colSpan - 1);
 217:                     }
 218:                     else if ($(this).attr('rowspan') !== undefined) {
 219:                         var rowspan = parseInt($(this).attr('rowspan'));
 220:                         col_height = rowspan * 30 + (rowspan - 1);
 221:                         $(this).height(col_height).css('border-bottom-style', 'none');
 222:                         col_width = colsLengsArr[colIndex];
 223:                         if (colIndex <= leftCols)
 224:                             gv_header_left.find('.gv-div-th').eq(colIndex).html('').css('border-top-style', 'none');
 225:                         else if (colIndex >= rightCols)
 226:                             gv_header_right.find('.gv-div-th').eq(colIndex - lockColumns).html('').css('border-top-style', 'none');
 227:                         colIndex++;
 228:                     }
 229:                     else {
 230:                         col_width = colsLengsArr[colIndex];
 231:                         colIndex++;
 232:                     }
 233:                     $(this).width(col_width);
 234:                 });
 235:             }
 236:             calcGroupCol(leftGroupCols);
 237:             calcGroupCol(rightGroupCols);
 238:  
 239:             gv_header_left.find('.gv-div-table').prepend(leftGroupCols);
 240:             gv_header_right.find('.gv-div-table').prepend(rightGroupCols);
 241:         }
 242:         else
 243:             dataAreaHeight -= 31;
 244:         if (dataAreaHeight > 0) {
 245:             gv_data_left.height(dataAreaHeight - 18);
 246:             gv_data_right.height(dataAreaHeight);
 247:         }
 248:         //设置滚动事件
 249:         $('.gv-data-right').scroll(function () {
 250:             $('.gv-data-left').scrollTop($(this).scrollTop());
 251:             $('.gv-header-right').scrollLeft($(this).scrollLeft());
 252:         });
 253:     }
 254: };

最后

虽然实现了上面的一些功能,但还是有些缺陷让人遗憾:

  1. 本人美工不行,样式上有些瑕疵。
  2. 测试过IE7、IE8、IE9与Chrome浏览器,目前是正常的,但Chrome浏览器可能有不兼容的情况出现。这点需要有时间慢慢解决。
  3. 不能支持超过2行以上的组合表头,不支持行合并。因为整个jqGridView均使用div组合,所以在行合并上是软肋,不知道各位朋友有什么好的方案没。

如果您对jqGridView感兴趣,或者有好的解决方案,或者对源码做了一些修正,请通知我。

最后,本人刚开了个拍拍商店,愿意捧场的朋友请点击下CodeLove1314的小店,想获取技术支持的或者想捧场的请点击下赞助,这年头,想真心编码不容易啊。

点此下载示例与源码

.net技术交流一群:85318032

转载于:https://www.cnblogs.com/codelove/archive/2012/07/29/2613716.html

相关文章:

Struts2--ActionContext及CleanUP Filter

1. ActionContext ActionContext是被存放在当前线程中的&#xff0c;获取ActionContext也是从ThreadLocal中获取的。所以在执行拦截器、 action和result的过程中&#xff0c;由于他们都是在一个线程中按照顺序执行的&#xff0c;所以可以可以在任意时候在ThreadLocal中获取 Act…

HTML5跳转页面并传值以及localStorage的用法

1、首先&#xff0c;你得在那个页面把数据存入localStorage中吧。这个是必须的&#xff01; localStorage.setItem("user",JSON.stringify(data.allUser)); 用localStorage的setItem方法&#xff0c;这个方法看名字都知道得差不多了吧。。。setItem把数据存入localSt…

冒泡排序_python实现冒泡排序

冒泡排序是比较经典的面试题&#xff0c; 它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换&#xff0c;也就是说该元素列已经…

30分钟内让你明白正则表达式是什么,并对它有一些基本的了解(二)

测试正则表达式 如果你不觉得正则表达式很难读写的话&#xff0c;要么你是一个搞笑的天才&#xff0c;要么&#xff0c;你不是地球人。正则表达式的语法很令人头疼&#xff0c;即使对经常使用它的人来说也是如此。由于难于读写&#xff0c;容易出错&#xff0c;所以找一种工具对…

(区间dp 或 记忆化搜素 )Brackets -- POJ -- 2955

http://poj.org/problem?id2955 Description We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a regular brackets sequence,if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences…

[初级]深入理解乐观锁与悲观锁

2019独角兽企业重金招聘Python工程师标准>>> 在数据库的锁机制中介绍过&#xff0c;数据库管理系统&#xff08;DBMS&#xff09;中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。 乐观并发控制(乐观锁…

Umbra 3:次世代的遮挡裁剪

原文链接&#xff1a;http://www.gamasutra.com/view/feature/164660/sponsored_feature_next_generation_.php?print1 来自 Umbra Software [在这个主办方特辑中&#xff0c;Umbra Software讨论了当前使用的大量裁剪遮挡方法的优缺点&#xff0c;并解释了它自己的自动化遮挡…

在64位机上PLSQL连oracle11g问题:SQL*Net not properly installed和ORA-12154:TNS:无法处理服务名...

今天有同事在给客户安装我们的系统时&#xff0c;出现了问题。 背景&#xff1a;同事安装如下&#xff1a; 服务器是小机&#xff0c;在小机上做的虚拟机。WIN&#xff12;&#xff10;&#xff10;&#xff13;操作系统&#xff0c;装的是&#xff16;&#xff14;位的。 数据…

ios 应用和电脑共享文件夹_堪比AirDrop,苹果 iPhone与Windows电脑互传文件的三种方式...

如果你是苹果全家桶用户&#xff0c;一定会对 「AirDrop(隔空投送)」 功能赞誉有加&#xff0c;使用 AirDrop 可以在 iPhone 与 MacBook、iPad 等设备之间快速传递照片、视频或文件。遗憾的是&#xff0c;「AirDrop 仅限苹果设备之间使用」&#xff0c;而很多小伙伴应该和小兽一…

Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性

1 数组排序 1.1 问题 本案例实现一个整型数组排序的函数&#xff0c;数组排序的规则由传递的规则函数决定。 1.2 方案 首先定义一个整型数组排序函数sortInts&#xff0c;该函数有一个整型数组类型的参数&#xff0c;该参数必须是输入输出参数inout&#xff0c;否则并不能修改数…

shell命令之---Linux文件权限

本章内容  理解Linux的安全性 解读文件权限 使用Linux组 1、Linux的安全性---/etc/passwd文件 # cat /etc/passwdroot:x:0:0:root:/root:/bin/bash/etc/passwd文件的字段包含了如下信息&#xff1a; 登录用户名 用户密码 用户账户的UID&#xff08;数字形式&#x…

失败原因_解析干洗店失败原因

在市面上我们其实也知道有的店面开张时间不长或者最终没有存活下来&#xff0c;干洗店也不例外。我们在看到各地干洗店的高额利润的同时&#xff0c;也会发现一些失败的干洗店。他们的干洗店为何难以运营下去呢?下面伊斯曼小编来在多个方面剖析一下其中的蹊跷和缘由&#xff1…

seg:NLP之正向最大匹配分词

已迁移到我新博客,阅读体验更佳seg:NLP之正向最大匹配分词 完整代码实现放在我的github上:click me 一、任务要求 实现一个基于词典与规则的汉语自动分词系统。二、技术路线 采用正向最大匹配(FMM)方法对输入的中文语句进行分词&#xff0c;具体的实现可以分为下面几个步骤&…

喷涂机器人保养应该注意的七个事项

喷涂机器人又叫喷漆机器人(spray painting robot)&#xff0c; 是可进行自动喷漆或喷涂其他涂料的工业机器人。目前市面上采用比较多的品牌有ABB、库卡、发那科等等&#xff0c;长时间的使用能加速工业机器人的老化&#xff0c;保养是延缓机器人老化的一大关键&#xff0c;那么…

K均值与C均值区别

k均值聚类&#xff1a;---------一种硬聚类算法&#xff0c;隶属度只有两个取值0或1&#xff0c;提出的基本根据是“类内误差平方和最小化”准则&#xff1b;  模糊的c均值聚类算法&#xff1a;-------- 一种模糊聚类算法&#xff0c;是k均值聚类算法的推广形式&#xff0c;隶…

中超赛程来100wan点in_不干了:中超球队改名“硬重启”,球迷组织绝望解散

聚焦中超和CBA&#xff0c;独一无二球迷媒体点击右上角关注&#xff0c;你不会后悔的...2021赛季中超注定会与众不同&#xff0c;足协的新规将陆续实施&#xff0c;如果降薪还在外界意料之中的话&#xff0c;那么更改中性化名字的要求则让多数俱乐部较为头疼&#xff0c;尤其是…

微博polg什么意思_贾磊:广东发微博给CBA造成了负面影响 方硕的意思可能没表达清楚...

直播吧11月5日讯 近日做客一档节目时&#xff0c;著名篮球记者贾磊谈到了前天晚上的京粤大战。贾磊谈到了王骁辉伸腿绊倒威姆斯一事&#xff1a;“我觉得这场比赛&#xff0c;王骁辉的这个动作&#xff0c;大家都看的非常清楚&#xff0c;确实是一个犯规&#xff0c;也给威姆斯…

iOS 中的网络请求 (同步请求、异步请求、GET请求、POST请求)

1、同步请求可以从因特网请求数据&#xff0c;一旦发送同步请求&#xff0c;程序将停止用户交互&#xff0c;直至服务器返回数据完成&#xff0c;才可以进行下一步操作&#xff0c; 2、异步请求不会阻塞主线程&#xff0c;而会建立一个新的线程来操作&#xff0c;用户发出异步请…

springboot 头像上传 文件流保存 文件流返回浏览器查看 区分操作系统 windows 7 or linux...

1 //我的会员中心 头像上传接口2 /*windows 调试*/3 Value("${appImg.location}")4 private String winPathPic;5 /*linux 使用*/6 Value("${img.location}")7 private String linuxPathPic;8 9 PostMapping(value "/file")10 public String f…

个人所得税计算器2016 by Jacksile

个人所得税计算器2016 个人所得税计算器2016 税前薪资&#xff1a;元各项社会保险费&#xff1a;元起征点&#xff1a;35004800元应缴税款&#xff1a;元实发薪资&#xff1a;元个人所得税计算公式 应纳税额 应纳税所得额 x 税率 &#xff0d; 速算扣除数 应纳税所得额 工资收…

interface IEngineControl封装引擎通用操作

using System; using System.Collections.Generic; using System.Text; using System.Linq; namespace SIAT {namespace Engine{/******************************************************************** 引擎控制接口&#xff0c;该类封装一些引擎中通用的操作* * ***********…

iOS 导航栏遮挡问题 --- iOS开发系列 ---项目中成长的知识七

不知大家有没有遇见过自己写的tableview被导航栏遮挡住的问题,反正我是遇见过! 因为在ios7以后所有的UIViewController创建后默认就是full Screen的&#xff0c;因此如果带导航栏的应用界面中的部分控件会被导航栏覆盖掉。 解决方案&#xff1a;可以使用ios7中的UIViewControll…

程序员笔记|如何编写优雅的Dockerfile

导读 Kubernetes要从容器化开始&#xff0c;而容器又需要从Dockerfile开始&#xff0c;本文将介绍如何写出一个优雅的Dockerfile文件。 文章主要内容包括&#xff1a; Docker容器 Dockerfile 使用多阶构建感谢公司提供大量机器资源及时间让我们可以实践&#xff0c;感谢在此专…

Oracle面试问题汇总

1:SqL 优化 1&#xff1a;尽量避免使用 select * 查询方式 因为oracle 在解析过程中 会将*依次转化成所以的列名。 2&#xff1a;减小访问数据库的次数 因为每执行一条sql语句的时候&#xff0c;oracle内部会做许多的事情 如&#xff1a;解析sql &#xff0c;估算索引的利用效率…

相关性分析p值_一行代码掌握皮尔逊相关分析,洞察变量关系

变量类型与推荐的假设检验方法可以看到&#xff0c;当我们探索两个连续变量之间的关系时&#xff0c;相关分析是一个很好的选择。那么&#xff0c;相关分析的原理是什么&#xff1f;如何在Python中实现相关分析呢&#xff1f;一、Pearson相关系数针对两个独立的服从正态分布的连…

润前报表简单问题

Q&#xff1a;设计器如何打开A&#xff1a;如果是安装的&#xff0c;那么直接到菜单下&#xff0c;打开润乾报表设计器就行了&#xff0c;如果是压缩包或者从别人那儿拷过来的&#xff0c;就运行\reportHome\bin下面的startup.bat就可以打开了。 Q&#xff1a;做一个报表最基本…

一个简单的slider滑块组件

2019独角兽企业重金招聘Python工程师标准>>> 我们先来看一张图片&#xff1a; 要实现这样的效果我们有很多种方法&#xff0c;比如直接使用<input type"range" />修改样式即可&#xff0c;也可用下面的这种方式修改 样式 HTML代码&#xff1a; <…

压测接口线程数设置_ZAT掌门性能压测巡检系统实战和落地

项目背景随着业务拓展&#xff0c;对于接口性能的要求也在上升&#xff0c;各部门也开始针对部分慢接口进行优化&#xff0c;从测试角度针对这些优化需求进行测试时不仅要保证对应接口的功能正常使用同时也要验证接口优化成果。在日常的开发工作中一些后台服务配置的改动也会对…

01python语言程序设计基础——初识python

1.python的字符串中format函数用法 format 函数可以接受不限个参数&#xff0c;位置可以不按顺序。In [2]:"{} {}".format("hello", "world") # 不设置指定位置&#xff0c;按默认顺序Out[2]:hello world In [3]:"{0} {1}".format(&q…

没有什么不可能(1)

近在读一本书《没有什么不可能》&#xff0c;书中宗旨就是&#xff1a;这个世界没有什么不可能&#xff0c;每个人的脚下都有一条通往成功的道路&#xff0c;信念是一切力量的源泉。这本书看了三分之一&#xff0c;跟大家分享一下前三个观点。 1、只有想不到&#xff0c;没有做…