ASP.NET MVC4+BootStrap 实战(十)
年过完了,也该收心了。想想过年这几天都是每天睡到12:00,实在是腐化。大家都沉浸在抢红包的喜悦之中。
不说了,今天我们主要看一下新闻链接管理界面。先上图,无图无真相。
上半部分主要是对已经添加的外链接进行修改删除,设置优先级,下半部分是新增外链接网站。
首先我们先看一下上半部分。
<div id="div_newsManage" class="panel panel-primary" ng-app="newsLinkManageModule" ng-controller="newsLinkManageController"> <div class="panel-heading"> <h3 class="panel-title"> <img class="img-panel-title" src="~/Images/Base/newslink.png" /> <b>新闻链接管理</b> </h3> </div> <div class="panel-body"> <fieldset> <legend> <h5><b>外链接管理</b></h5> </legend> <div class="row"> <div class="col-md-1"> <input type="checkbox" ng-model="IsSelectAll" /> </div> <label class="col-md-5" style="color:#333333">网站名称</label> <label class="col-md-2" style="color:#333333">TOP(X)</label> <label class="col-md-2" style="color:#333333">操作</label> <label class="col-md-2" style="color:#333333">优先级</label> </div> <div class="line-seperate-style-main"></div> <div ng-repeat="website in WebSites" class="a-list"> <div class="row" style="line-height:40px"> <div class="col-md-1"> <input class="chklist-vertical-align" type="checkbox" ng-model="website.IsChecked" /> </div> <div class="col-md-5"> <a href="{{website.WebSiteURL}}">{{website.WebSiteName}}</a> </div> <div class="col-md-2"> <select class="form-control" ng-model="website.TopNewsCount" ng-options="number for number in numbers"> @*<option ng-repeat="num in numbers" label="{{num}}" value="{{num}}"></option>*@ </select> </div> <div class="col-md-2"> <span style="cursor: pointer;" class="glyphicon glyphicon-pencil span-grid"></span> <span ng-click="newslinkdeleteSingle(website.TransactionNumber)" style="cursor:pointer;margin-left:5px;" class="glyphicon glyphicon-trash span-grid"></span> </div> <div class="col-md-2"> <span style="cursor:pointer;" class="glyphicon glyphicon-arrow-up span-grid"></span> <span style="cursor: pointer; margin-left: 5px;" class="glyphicon glyphicon-arrow-down span-grid"></span> </div> </div> <div class="line-seperate-style"></div> </div> <input type="button" value="移除" ng-click="newslinkdelete()" style="margin-top:10px" class="btn btn-danger" /> </fieldset>
还是bootStrap布局,将div分成1,5,2,2,2比例的五等份。我们通过ng-repeat生成多行div。在这里需要注意的是这里的select标签的ng-options,在这里如果不使用ng-options的话,ng-model是无法选中的。OK,我们看到头部有一个复选框,那个复选框是用来全选和反选的。OK,我们看一下js代码
var appModule = angular.module(‘newsLinkManageModule‘, []); appModule.controller("newsLinkManageController", function ($scope, $http, $filter) { initData(); $scope.AddedWebSites = []; $scope.numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; $scope.IsSelectAll = false;
在页面加载以后,我们首先会调用initData方法。
function initData() { $http.get("/NewsManage/NewsLinkList").success(function (data) { $scope.WebSites = data; }); };
其实就是调用一个后台action,得到WebSites。
[HttpGet] [OutputCache(Duration = 60)] public JsonResult NewsLinkList() { var newsEntityList = NewsMngBiz.GetInstance().GetNewsLinkList(); if (newsEntityList == null) return null; return Json(newsEntityList, JsonRequestBehavior.AllowGet); }
在这里,实体的定义如下
public class NewsLinkEntity { public int TransactionNumber { get; set; } public string WebSiteName { get; set; } public string WebSiteURL { get; set; } public int TopNewsCount { get; set; } public int Priority { get; set; } }
就是将这样一个实体list以json格式返回到客户端。全选和全不选的js代码如下
$scope.$watch("IsSelectAll", setCheckState); function setCheckState(newValue, oldValue) { angular.forEach($scope.WebSites, function (obj, key) { obj.IsChecked = newValue; }); }
我们通过监控IsSelectAll的值来实时设置列表中的选中状态。
接着我们看一下这里移除按钮的实现。
var linkIDs = []; $scope.newslinkdelete = function () { linkIDs = []; angular.forEach( $filter(‘filter‘)($scope.WebSites, { IsChecked: true }), function (v) { linkIDs.push(v.TransactionNumber); } ); if (linkIDs.length == 0) { alert("请选择要删除的数据!"); return; } if (confirm("您确定要删除吗?")) { var param = { requestJson: JSON.stringify({ linkIDs: linkIDs }) }; newsLinkDelete(param); } };
在这里先拿到选中的TransactionNumber,然后发送到服务端进行处理。
function newsLinkDelete(param) { $http({ method: "Delete", url: "/NewsManage/DeleteNewsLink", headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ }, data: $.param(param) }).success(function (data, status, headers, config) { alert(data.msg); if (data.suc == 1) { initData(); } }).error(function (data, status, headers, config) { alert(status); }); }
我们看一下服务端的处理
[HttpDelete] public JsonResult DeleteNewsLink() { string requestJson = Request["requestJson"]; string[] linkIDArray = JsonBuilder.BuildStringArray(requestJson, "linkIDs"); int suc = NewsMngBiz.GetInstance().DeleteNewsLinks(linkIDArray); if (suc >= 0) { return GetJsonMessage("CM_002", JsonMsgType.SUCCESS); } return GetJsonMessage("CM_005"); }
DAL层调用如下的脚本进行处理
DECLARE @NewsLinkIDTable TABLE ( ID INT IDENTITY(1,1), TransactionNumber INT NOT NULL ) INSERT INTO @NewsLinkIDTable ( TransactionNumber ) SELECT short_str FROM dbo.F_SQLSERVER_SPLIT(@NewsLinkIDs,‘,‘) DELETE A FROM dbo.InformationNewsLink A WHERE EXISTS( SELECT TOP 1 1 FROM @NewsLinkIDTable B WHERE B.TransactionNumber = A.TransactionNumber )
OK,接下来我们看一下下半部分。下半部分,当用户点击新增按钮的时候,会动态增加一个用于添加链接网站的div。
看一下代码
<fieldset style="margin-top:20px"> <legend> <h5><b>外链接新增</b></h5> </legend> <div class="row"> <label class="col-md-1">序号</label> <label class="col-md-1">勾选</label> <label class="col-md-4">网站名称</label> <label class="col-md-6">网站URL</label> </div> <div class="line-seperate-style-main"></div> <div class="row" style="line-height:40px"> <div class="col-md-1"> <div class="div-circal-list">1</div> </div> <div class="col-md-1"> <input disabled type="checkbox" ng-model="IsChecked" class="chklist-vertical-align" /> </div> <div class="col-md-4"> <input type="text" ng-model="WebSiteName" maxlength="30" style="width:100%" class="form-control" /> </div> <div class="col-md-6"> <input type="text" placeholder="请以http或者https开头" maxlength="200" ng-model="WebSiteURL" style="width:100%" class="form-control" /> </div> </div> <div ng-repeat="website in AddedWebSites"> <div class="row" style="line-height:40px"> <div class="col-md-1"> <div class="div-circal-list">{{$index + 2}}</div> @*<img src="~/Images/orderedList{{$index + 1}}.png" />*@ </div> <div class="col-md-1"> <input type="hidden" value="{{$index + 1}}" ng-model="website.Index" /> <input type="checkbox" ng-model="website.IsChecked" class="chklist-vertical-align" /> </div> <div class="col-md-4"> <input type="text" ng-model="website.LinkName" maxlength="30" style="width:100%" class="form-control" /> </div> <div class="col-md-6"> <input type="text" placeholder="请以http或者https开头" maxlength="200" ng-model="website.URL" style="width:100%" class="form-control" /> </div> </div> </div> <div style="margin-top:20px"> <input type="button" class="btn btn-primary" value="新增" ng-click="addnewlink()" /> <input type="button" class="btn btn-info" value="保存" /> <input type="button" class="btn btn-danger" value="移除" ng-click="removelink()" /> </div> </fieldset>
这个界面上第一个复选框是disabled,因为我们始终要保持一个表单在。在这里我们表单的新增其实就是通过更新model实现的。当我们给数组中新增一个对象时,界面就会自动新增一行。我们看一下实现
$scope.addnewlink = function () { if ($scope.AddedWebSites.length >= 9) { alert("您一次最多只能添加10个网站链接!"); return; } $scope.AddedWebSites.push({ URL: "", LinkName: "" }); };
很简单,前面的圆圈序列号是由如下div实现的。
<div class="div-circal-list">{{$index + 2}}</div>
css代码很简单。
.div-circal-list { width:30px; height:30px; border-radius:50%; background-color:#428bca; text-align:center; line-height:30px; color:white; }
我们再看一下移除。
$scope.removelink = function () { var selectedIDs = []; angular.forEach($scope.AddedWebSites, function (obj, key) { if (obj.IsChecked) { selectedIDs.push(key); } }); var num = 0; angular.forEach(selectedIDs, function (value, key) { $scope.AddedWebSites.splice(value - num, 1); ++num; }); };
在这里我们根据数组的下标进行删除。因为每删除一行,会重新生成一个$index,所以我们必须先把选中的index放到一个数组中,然后循环从列表中删除。因为每删除一个index就会减1,所以我们就每次value-num。OK,本篇到此结束。
最后我们看一下上节遗留的Excel导出功能,其实就是将form提交到如下action
[OutputCache(Duration = 60, NoStore = true)] [HttpPost] public FileResult Export(FormCollection fc) { string userID = fc["searchUserID"]; string userName = fc["searchUserName"]; string userSex = fc["searchUserSex"]; string birthDayStart = fc["searchStartDate"]; string birthDayEnd = fc["searchEndDate"]; string pageIndex = fc["hfdPageIndex"]; string pageSize = fc["hfdPageSize"]; UserSearchRequest userSearchRequest = new UserSearchRequest() { UserID = userID, UserName = userName, UserSex = userSex, StartDate = string.IsNullOrEmpty(birthDayStart) ? null : (DateTime?)DateTime.Parse(birthDayStart), EndDate = string.IsNullOrEmpty(birthDayEnd) ? null : (DateTime?)DateTime.Parse(birthDayEnd), PageIndex = int.Parse(pageIndex), PageSize = int.Parse(pageSize) }; byte[] fileBytes = UserInfoBiz.GetInstance().GetExportFileBytes(userSearchRequest); if (fileBytes == null) return File("~/NoData.xls", "application/ms-excel"); return File(fileBytes, "application/ms-excel", string.Concat("UserInfo", Guid.NewGuid().ToString(), ".xls")); }
在这里我们通过NPOI组件返回个byte数组,通过Biz层调用得到数组,在action中输出到客户端。
public static byte[] ExportExcel(DataTable dt, string title) { HSSFWorkbook workbooks = new HSSFWorkbook(); HSSFSheet worksheet = (HSSFSheet)workbooks.CreateSheet(title); if (dt.Rows.Count == 0) { return null; } //标题 int titleCell = dt.Columns.Count; worksheet.AddMergedRegion(new Region(0, 0, 0, titleCell - 1));//合并单元格,第0行0列开始到第0行titleCell-1列 HSSFCell cell = (HSSFCell)worksheet.CreateRow(0).CreateCell(0);//创建单元格 cell.SetCellValue(title); //设置样式 HSSFCellStyle style = (HSSFCellStyle)workbooks.CreateCellStyle(); HSSFFont font = (HSSFFont)workbooks.CreateFont(); font.Boldweight = (short)FontBoldWeight.BOLD;//粗体 font.Color = HSSFColor.RED.index;//字体颜色 red font.FontHeightInPoints = 18;//字体大小 style.SetFont(font); style.Alignment = HorizontalAlignment.CENTER; cell.CellStyle = style; //设置样式 HSSFCellStyle style1 = (HSSFCellStyle)workbooks.CreateCellStyle(); HSSFFont font1 = (HSSFFont)workbooks.CreateFont(); font1.Boldweight = (short)FontBoldWeight.BOLD;//粗体 font1.FontHeightInPoints = 12;//字体大小 style1.SetFont(font1); style1.WrapText = false; style1.Alignment = HorizontalAlignment.LEFT; HSSFRow row1 = (HSSFRow)worksheet.CreateRow(1); //写入字段 for (int i = 0; i < dt.Columns.Count; i++) { HSSFCell cell1 = (HSSFCell)row1.CreateCell(i);//创建单元格 cell1.SetCellValue(dt.Columns[i].ColumnName); cell1.CellStyle = style1; } for (int r = 0; r < dt.Rows.Count; r++) { HSSFRow rowr = (HSSFRow)worksheet.CreateRow(r + 2); for (int c = 0; c < dt.Columns.Count; c++) { HSSFCell cell2 = (HSSFCell)rowr.CreateCell(c);//创建单元格 var aa = dt.Columns[c].DataType.ToString(); var cellvalue = dt.Rows[r][dt.Columns[c].ColumnName].ToString(); #region switch (dt.Columns[c].DataType.ToString()) { case "System.String"://字符串类型 cell2.SetCellValue(cellvalue); break; case "System.Nullable`1[System.DateTime]"://日期类型 case "System.DateTime": DateTime dateV; DateTime.TryParse(cellvalue, out dateV); cell2.SetCellValue(cellvalue); break; case "System.Boolean"://布尔型 bool boolV = false; bool.TryParse(cellvalue, out boolV); cell2.SetCellValue(cellvalue); break; case "System.Int16"://整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(cellvalue, out intV); cell2.SetCellValue(cellvalue); break; case "System.Decimal"://浮点型 case "System.Double": double doubV = 0; double.TryParse(cellvalue, out doubV); cell2.SetCellValue(cellvalue); break; case "System.DBNull"://空值处理 cell2.SetCellValue(""); break; default: cell2.SetCellValue(""); break; } #endregion } } try { using (MemoryStream ms = new MemoryStream()) { workbooks.Write(ms); ms.Flush(); ms.Position = 0; worksheet.Dispose(); workbooks.Dispose(); byte[] data = ms.ToArray(); GC.Collect(); return data; } } catch (Exception ex) { LogHelper.WriteExceptionLog(MethodBase.GetCurrentMethod(),ex); return null; } }
Ok,我们看一下效果
打开Excel,结果如下,样式没有细调。
最后祝大家在新的一年里一顺百顺事事顺,欢天喜地迎新年。
本文出自 “技术创造价值” 博客,请务必保留此出处http://leelei.blog.51cto.com/856755/1615085
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。