一、前台代码和js代码:
<body> <!----------------新闻列表开始------------------------> <div> <a href="javascript:void(0)" id="addInfo">添加</a> @if (ViewData["NewsList"] != null) { <table width="100%"> <tr> <th>编号</th> <th>标题</th> <th>作者</th> <th>时间</th> <th>详细</th> <th>删除</th> <th>修改</th> </tr> @foreach (NewsInfo newInfo in (List<NewsInfo>)ViewData["NewsList"]) { <tr> <td>@newInfo.Id</td> <td>@newInfo.Title</td> <td>@newInfo.Author</td> <td>@newInfo.SubDateTime</td> <td><a href="javascript:void(0)" class="details" ids="@newInfo.Id">详细</a></td> <td><a href="javascript:void(0)" class="deletes" ids="@newInfo.Id">删除</a></td> <td><a href="javascript:void(0)" class="alters" ids="@newInfo.Id">修改</a></td> </tr> } </table> //自定义页码条 <div class="paginator">@YpfMVCHtmlPaging.ShowPageNavigate(this.Html, ViewBag.currentPage, ViewBag.pageSize, ViewBag.totalCount)</div> } else { <span>暂无数据</span> } </div> <!----------------新闻列表结束------------------------> <!----------------显示详细信息内容------------------------> <div id="detailDiv"> <table> <tr> <td>标题</td> <td><span id="title"></span></td> </tr> <tr> <td>作者</td> <td><span id="author"></span></td> </tr> <tr> <td>时间</td> <td><span id="subDateTime"></span></td> </tr> <tr> <td>内容</td> <td><span id="msg"></span></td> </tr> </table> </div> <!----------------显示详细信息内容结束------------------------> <!----------------添加信息内容------------------------> <div id="addTailDiv" style="overflow: hidden"> <iframe id="AddFrame" src="/AdminNewsList/AddInfo" frameborder="0" scrolling="auto" width="100%" height="100%"></iframe> </div> <!----------------添加信息内容结束------------------------> <!---------------编辑用户信息----------------------> <div id="editInfoDiv" style="overflow: hidden"> <iframe id="editInfoFrame" src="/AdminNewsList/ShowEdit" scrolling="auto" frameborder="0" width="100%" height="100%"></iframe> </div> <!---------------编辑用户信息结束----------------------> </body>
<script type="text/javascript"> $(function () { $("#detailDiv").css("display", "none");//详细信息隐藏 $("#addTailDiv").css("display", "none");//添加隐藏 $("#editInfoDiv").css("display", "none"); //详细。。。 $(".details").click(function () { var newID = $(this).attr("ids"); ShowEntity(newID); }); //删除。。。 $(".deletes").click(function () { var newID = $(this).attr("ids"); deleteInfo(newID, $(this)); }); $("#addInfo").click(function () { addNewsInfo(); }); //修改 $(".alters").click(function () { var newsID = $(this).attr("ids"); alter(newsID); }); }); //显示详细信息 function ShowEntity(newID) { //异步获取指定id数据 $.post("/AdminNewsList/GetNewInfoModel", { id: newID }, function (data) { $("#title").text(data.Title); $("#author").text(data.Author); $("#subDateTime").text(ChangeDateFormat(data.SubDateTime)); $("#msg").html(data.Msg); }); $("#detailDiv").css("display", "block");//详细信息显示 //对话框方式显示 $('#detailDiv').dialog({ modal: true, resizable: true, maximizable: true, collapsible: true, title: "新闻详细", width: 400, height: 300 }); } //将序列化成(/Date(1354648740000)/)json格式后日期(毫秒数)转成日期格式 function ChangeDateFormat(jsonDate) {//json日期格式转换为正常格式 try { var date = new Date(parseInt(jsonDate.replace("/Date(", "").replace(")/", ""), 10)); var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); var hours = date.getHours(); var minutes = date.getMinutes(); var seconds = date.getSeconds(); var milliseconds = date.getMilliseconds(); return date.getFullYear() + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds + "." + milliseconds; } catch (ex) { return ""; } } //删除信息 function deleteInfo(newid, control) { $.messager.confirm('提醒:', '确定要删除吗?', function (r) { if (r) { //异步处理删除数据 $.post("/AdminNewsList/DeleteInfo", { id: newid }, function (data) { if (data = "yes") { $.messager.show({ title: '提示:', msg: '删除成功!', timeout: 3000, showType: 'slide' }); $(control).parent().parent().remove(); } else if (data = "no") { $.messager.alert("提示:", "删除失败!", "info"); } else { $.messager.alert("提示:", "删除失败!", "info"); } }); } }); } //添加 function addNewsInfo() { $("#AddFrame").attr("src", "/AdminNewsList/AddInfo"); $("#addTailDiv").css("display", "block"); $('#addTailDiv').dialog({ modal: true, resizable: true, collapsible: true, title: "添加新闻", width: 700, height: 400, buttons: [{ text: '确定', iconCls: 'icon-ok', handler: function () { var childWindow = $("#AddFrame")[0].contentWindow; childWindow.subForm(); } }, { text: '取消', handler: function () { $('#addTailDiv').dialog('close'); } }] }); } //添加成功后 function IndexAddAfter() { $('#addTailDiv').dialog('close');//成功后关闭窗体 $.messager.show({//成功后提示消息框 title: '提示:', msg: '添加成功!', timeout: 3000, showType: 'slide' }); } //+修改 function alter(newsID) { $("#editInfoFrame").attr("src", "/AdminNewsList/ShowEdit?id=" + newsID); $("#editInfoDiv").css("display", "block"); $('#editInfoDiv').dialog({ modal: true, resizable: true, collapsible: true, title: "修改新闻", width: 700, height: 400, buttons: [{ text: '修改', iconCls: 'icon-ok', handler: function () { var childWindow = $("#editInfoFrame")[0].contentWindow; childWindow.SubForm(); } }, { text: '取消', handler: function () { $('#editInfoDiv').dialog('close'); } }] }); } function afterEdit() { $('#editInfoDiv').dialog('close'); $.messager.show({//成功后提示消息框 title: '提示:', msg: '修改成功!', timeout: 3000, showType: 'slide' }); } </script>
在这个页面中我们将“新闻分页展示”,“新闻添加”,“新闻修改”,“新闻删除”全部放在一个页面中,当然“添加”和“修改”我们使用iframe进行展示。
二、前台代码分析:
1、新闻分页展示
采用了前台table布局+后台viewData数据传输方式显示。并且采用了自定义的mvc分页控件。
1-1、自定义mvc分页控件代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace System.Web.Mvc { public static class YpfMVCHtmlPaging { /// <summary> /// 分页控件---自定义YPF /// </summary> /// <param name="htmlHelper">this.Html</param> /// <param name="currentPage">当前页码</param> /// <param name="pageSize">每页容量</param> /// <param name="totalCount">总条数</param> /// <returns></returns> public static MvcHtmlString ShowPageNavigate(this HtmlHelper htmlHelper, int currentPage, int pageSize, int totalCount) { var redirectTo = htmlHelper.ViewContext.RequestContext.HttpContext.Request.Url.AbsolutePath;//获取当前页面的url地址不包括参数 pageSize = pageSize == 0 ? 3 : pageSize;//默认3页 var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数 var output = new StringBuilder(); if (totalPages > 1) { //if (currentPage != 1) {//处理首页连接 output.AppendFormat("<a class='pageLink' href='{0}?pageIndex=1&pageSize={1}'>首页</a> ", redirectTo, pageSize); } if (currentPage > 1) {//处理上一页的连接 output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>上一页</a> ", redirectTo, currentPage - 1, pageSize); } else { // output.Append("<span class='pageLink'>上一页</span>"); } output.Append(" "); int currint = 5; for (int i = 0; i <= 10; i++) {//一共最多显示10个页码,前面5个,后面5个 if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages) { if (currint == i) {//当前页处理 //output.Append(string.Format("[{0}]", currentPage)); output.AppendFormat("<a class='cpb' href='{0}?pageIndex={1}&pageSize={2}'>{3}</a> ", redirectTo, currentPage, pageSize, currentPage); } else {//一般页处理 output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>{3}</a> ", redirectTo, currentPage + i - currint, pageSize, currentPage + i - currint); } } output.Append(" "); } if (currentPage < totalPages) {//处理下一页的链接 output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>下一页</a> ", redirectTo, currentPage + 1, pageSize); } else { //output.Append("<span class='pageLink'>下一页</span>"); } output.Append(" "); if (currentPage != totalPages) { output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>末页</a> ", redirectTo, totalPages, pageSize); } output.Append(" "); } output.AppendFormat("第{0}页 / 共{1}页", currentPage, totalPages);//这个统计加不加都行 return MvcHtmlString.Create(output.ToString()); } } }
分页控件样式表
body { } .paginator { font: 12px Arial, Helvetica, sans-serif; padding: 10px 20px 10px 0; margin: 0px; } .paginator a { border: solid 1px #ccc; color: #0063dc; cursor: pointer; text-decoration: none; } .paginator a:visited { padding: 1px 6px; border: solid 1px #ddd; background: #fff; text-decoration: none; } .paginator .cpb { border: 1px solid #F50; font-weight: 700; color: #F50; background-color: #ffeee5; } .paginator a:hover { border: solid 1px #F50; color: #f60; text-decoration: none; } .paginator a, .paginator a:visited, .paginator .cpb, .paginator a:hover { float: left; height: 16px; line-height: 16px; min-width: 10px; _width: 10px; margin-right: 5px; text-align: center; white-space: nowrap; font-size: 12px; font-family: Arial,SimSun; padding: 0 3px; }
2、新闻详细页
这里我们将详细页套入了easyUi的对话框效果。将异步获取到的数据在对话框效果中进行展示。
注意:①由于返回的数据是json格式,那么它会将时间数据进行格式转换“/Date(1354648740000)/”,我们想要得到原来的日期格式则需要调用下这个 function ChangeDateFormat(cellval)函数即可。
②新闻内容中由于我们使用了js富文本控件,所以里面的内容会有html标签,那么我们只需要将“ $("#msg").html(data.Msg);”而不是将“ $("#msg").text(data.Msg);”
3、新闻添加页
我们将新闻添加页面采用iframe方式单独放在一个页面中。在这个页面我们继续使用了easyUI的对话框样式。
注意:我们在对话框中显示的是另外一个页面内容,也可以看成是当前页面的子页面。当我们点击“添加”按钮的时候,就是在当前页面去提交子页面的表单内容。那么这里我就用到了在当前页面调用子页面的表单提交事件。下面这段js代码就是在当前页面调用子页面的表单提交函数(subForm)!
var childWindow = $("#AddFrame")[0].contentWindow;
childWindow.subForm();
添加页面我们主要采用了第三方的富文本控件,下面是具体代码:
<html> <head> <meta name="viewport" content="width=device-width" /> <title>添加新闻</title> <link href="~/Content/themes/tableStyle.css" rel="stylesheet" /> <script src="/KinderEditor/kindeditor-min.js"></script> <link rel="stylesheet" href="/KinderEditor/themes/default/default.css" /> <link rel="stylesheet" href="/KinderEditor/plugins/code/prettify.css" /> <script charset="utf-8" src="/KinderEditor/kindeditor.js"></script> <script charset="utf-8" src="/KinderEditor/lang/zh_CN.js"></script> <script charset="utf-8" src="/KinderEditor/plugins/code/prettify.js"></script> <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Scripts/MyAjaxForm.js"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> <link href="~/Content/themes/icon.css" rel="stylesheet" /> <link href="~/Content/themes/default/easyui.css" rel="stylesheet" /> <script src="~/Scripts/easyui-lang-zh_CN.js"></script> <script src="~/Scripts/jquery.easyui.min.js"></script> <script type="text/javascript"> //富文本 KindEditor.ready(function (K) { var editor1 = K.create('#MsgContent', { cssPath: '/KinderEditor/plugins/code/prettify.css', uploadJson: '/KinderEditor/asp.net/upload_json.ashx', fileManagerJson: '/KinderEditor/asp.net/file_manager_json.ashx', allowFileManager: true, afterBlur: function () { this.sync(); },//注意这里(异步提交时需要同步) afterCreate: function () { var self = this; self.sync();//把富文本编辑器的内容放到 文本域里面去。 } }); prettyPrint();//注意要调用该方法. }); $(function () { //图片上传 $("#btnFileUp").click(function () { fileUpLoad(); }); }); //+图片上传 function fileUpLoad() { if ($("#fileUpImage").val() == "") { $.messager.alert("提示:", "请选择上传图片!", "info"); return; } //异步的ajax表单提交--图片上传 $("#addForm").ajaxSubmit({ type: 'post', url: '/AdminNewsList/FileUpload', success: function (data) { var serverData = data.split(':'); if (serverData[0] == "ok") { $("#hidImage").attr("value", serverData[1]);//将服务端返回的图片路径赋给隐藏域 $("#menuIconShow").append("<img src='" + serverData[1] + "' width='40px' height='40px' />"); } else { $.messager.alert("提示", "图片上传错误!"); } } }); } function subForm () { $("#addForm").submit(); }; //表单整个异步提交的回调函数 function afterAdd() { window.parent.IndexAddAfter(); } </script> </head> <body> <div> @using (Ajax.BeginForm("addNewsInfo", "AdminNewsList", new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterAdd" }, new { id = "addForm" })) { <table> <tr> <td>新闻名称</td> <td> <input type="text" id="Title" name="Title" /></td> </tr> <tr> <td>作者</td> <td> <input type="text" id="Author" name="Author" /></td> </tr> <tr> <td>上传图片</td> <td> <input type="file" name="fileUpImage" id="fileUpImage" /> <input type="button" value="上传" id="btnFileUp"> <input type="hidden" id="hidImage" name="ImagePath" /> <div id="menuIconShow"> </div> </td> <tr> <td>新闻内容</td> <td> <textarea id="MsgContent" cols="100" rows="8" style="width: 500px; height: 200px; visibility: hidden;" name="Msg"></textarea> </tr> </tr> </table> } </div> </body> </html>
注意:
①富文本引用:引用它所需要的js和css。
<script src="/KinderEditor/kindeditor-min.js"></script> <link rel="stylesheet" href="/KinderEditor/themes/default/default.css" /> <link rel="stylesheet" href="/KinderEditor/plugins/code/prettify.css" /> <script charset="utf-8" src="/KinderEditor/kindeditor.js"></script> <script charset="utf-8" src="/KinderEditor/lang/zh_CN.js"></script> <script charset="utf-8" src="/KinderEditor/plugins/code/prettify.js"></script>
js中进行调用富文本,需要注意的是文本域Id。
<script type="text/javascript"> //富文本 KindEditor.ready(function (K) { var editor1 = K.create('#MsgContent', { cssPath: '/KinderEditor/plugins/code/prettify.css', uploadJson: '/KinderEditor/asp.net/upload_json.ashx', fileManagerJson: '/KinderEditor/asp.net/file_manager_json.ashx', allowFileManager: true, afterBlur: function () { this.sync(); },//注意这里(异步提交时需要同步) afterCreate: function () { var self = this; self.sync();//把富文本编辑器的内容放到 文本域里面去。 } }); prettyPrint();//注意要调用该方法. }); </script>
②在这个富文本控件里面使用到了图片上传功能。那么我们的项目必须要引用该图片上传所需要的“LitJSON.dll”这个类库。
③这个表单我们采用的是mvc的异步表单提交方式。那么我们就必须要引用js代码。
<script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
在异步表单提交成功的回调函数。我们的原理是:当表单提交成功后,就调用父页面的关闭按钮函数,并且调用easyUI的消息显示功能。
子页面调用父页面函数:
window.parent.IndexAddAfter();
④我们自定义的图片上传功能。
原理:图片上传我们使用了异步的方式提交表单内容,将提交的内容进行类型、大小等判断后存入文件中,然后返回其存储的物理路径。并在<img>标签中显示。
异步表单提交js。
<script src="~/Scripts/MyAjaxForm.js"></script> //js中调用异步函数 $(function () { //图片上传 $("#btnFileUp").click(function () { fileUpLoad(); }); }); //+图片上传 function fileUpLoad() { if ($("#fileUpImage").val() == "") { $.messager.alert("提示:", "请选择上传图片!", "info"); return; } //异步的ajax表单提交--图片上传 $("#addForm").ajaxSubmit({ type: 'post', url: '/AdminNewsList/FileUpload', success: function (data) { var serverData = data.split(':'); if (serverData[0] == "ok") { $("#hidImage").attr("value", serverData[1]);//将服务端返回的图片路径赋给隐藏域 $("#menuIconShow").append("<img src='" + serverData[1] + "' width='40px' height='40px' />"); } else { $.messager.alert("提示", "图片上传错误!"); } } }); }
异步上传的后台代码:
#region 图片上传 /// <summary> /// 图片上传 /// </summary> /// <returns></returns> public ActionResult FileUpload() { HttpPostedFileBase hpfb = Request.Files["fileUpImage"]; //我们可以对上传的文件进行各种判断。大小、类型等等。 if (hpfb == null) { return Content("no:请选择上传文件!"); } else { string fileName = Path.GetFileName(hpfb.FileName);//获取文件名称 string fileExc = Path.GetExtension(hpfb.FileName);//获取文件扩展名 if (fileExc == ".jpg") { string dirPath = "/ImagesPath" + "/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/"; Directory.CreateDirectory(Server.MapPath(dirPath));//创建保存图片文件夹--根据虚拟路径获得文件在磁盘的物理路径 string newFileName = Guid.NewGuid().ToString();//新文件名 string newFilePath = dirPath + newFileName + fileExc;//保存文件路的路径 hpfb.SaveAs(Server.MapPath(newFilePath));//保存文件 return Content("ok:" + newFilePath); } else { return Content("no:文件格式错误!"); } } } #endregion
4、新闻删除:
新闻删除采用了easyUI的confirm弹窗提示,并且采用了ajax方式提交处理数据。当然在数据删除后我们也要将当前页面显示的已经删除的数据从表格中删掉。
5、新闻修改:
新闻修改我们采用方式和添加的页面相同,只是在新闻修改页面进行加载显示的时候,我们要将gaitiao新闻对象提前查询到后加载到该页面中进行显示。
前台代码
<html> <head> <meta name="viewport" content="width=device-width" /> <title>修改闻信息</title> <link href="~/Content/themes/tableStyle.css" rel="stylesheet" /> <script src="/KinderEditor/kindeditor-min.js"></script> <link rel="stylesheet" href="/KinderEditor/themes/default/default.css" /> <link rel="stylesheet" href="/KinderEditor/plugins/code/prettify.css" /> <script charset="utf-8" src="/KinderEditor/kindeditor.js"></script> <script charset="utf-8" src="/KinderEditor/lang/zh_CN.js"></script> <script charset="utf-8" src="/KinderEditor/plugins/code/prettify.js"></script> <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> <script src="~/Scripts/MyAjaxForm.js"></script> <script type="text/javascript"> KindEditor.ready(function (K) { var editor1 = K.create('#MsgContent', { cssPath: '/KinderEditor/plugins/code/prettify.css', uploadJson: '/KinderEditor/asp.net/upload_json.ashx', fileManagerJson: '/KinderEditor/asp.net/file_manager_json.ashx', allowFileManager: true, afterBlur: function () { this.sync(); },//注意这里(异步提交时需要同步) afterCreate: function () { var self = this; self.sync();//把富文本编辑器的内容放到 文本域里面去。 } }); prettyPrint();//注意要调用该方法. }); $(function () { bindFileUpload(); }); //文件异步上传 function bindFileUpload() { $("#btnUpload").click(function () { if ($("#fileUpImage").val() == "") { $.messager.alert("提示", "请选择图片文件"); return; } $("#editForm").ajaxSubmit({ type: 'post', url: '/AdminNewsList/FileUpload', success: function (data) { var serverData = data.split(':'); if (serverData[0] == "ok") { $("#hidImage").attr("value", serverData[1]);//将服务端返回的图片路径赋给隐藏域 $("#menuIconShow").html("");//先清除以前的,然后再添加。 $("#menuIconShow").append("<img src='" + serverData[1] + "' width='40px' height='40px' />"); } else { $.messager.alert("提示", "图片上传错误!"); } } }); }); } //提交表单 function SubForm() { $("#editForm").submit(); } function afterEdit(data) { window.parent.afterEdit(data); } </script> </head> <body> <div> @using (Ajax.BeginForm("EditNewInfo", new { }, new AjaxOptions() { OnSuccess = "afterEdit" }, new { id = "editForm" })) { <input type="hidden" name="SubDateTime" value="@Model.SubDateTime" /> <input type="hidden" name="Id" value="@Model.Id" /> <table> <tr> <td>新闻名称</td> <td> <input type="text" name="Title" value="@Model.Title" /></td> </tr> <tr> <td>作者</td> <td> <input type="text" name="Author" value="@Model.Author" /></td> </tr> <tr> <td>上传图片:</td> <td> <input type="file" name="fileUpImage" id="fileUpImage" /><input type="button" id="btnUpload" value="异步上传" /> <input type="hidden" id="hidImage" name="ImagePath" value="@Model.ImagePath" /> <div id="menuIconShow"> <img src="@Model.ImagePath" id="imgPath" width="40px" height="40px"/> </div> </td> </tr> <tr> <td>新闻内容</td> <td> <textarea id="MsgContent" cols="100" rows="8" style="width: 500px; height: 200px; visibility: hidden;" name="Msg">@Model.Msg</textarea> </td> </tr> </table> } </div> </body> </html>
后台代码
#region 展示修改 /// <summary> /// 展示修改 /// </summary> /// <param name="news"></param> /// <returns></returns> public ActionResult ShowEdit() { if (Request["id"] == null) { return Content("数据异常!"); } int id = int.Parse(Request["id"]); NewsInfo newInfo = newsBLL.GetModel(id); ViewData.Model = newInfo; return View(); } #endregion #region 修改数据 /// <summary> /// 修改数据 /// </summary> /// <param name="news"></param> /// <returns></returns> [ValidateInput(false)] public ActionResult EditNewInfo(NewsInfo news) { if (newsBLL.Alter(news)) { return Content("ok"); } else { return Content("no"); } } #endregion
注意:在进行修改数据展示的后台代码中,我们使用了ASP.NET MVC提供了一种利用强类型的方法来将数据或对象传递到视图模板中。这种强类型的方法为你的编码过程提供了很丰富的编辑时的智能输入提示信息与非常好的编译时的检查。ViewData.Model = newInfo;
通过在视图模板文件的头部使用@model语句,视图模板可以识别传入的参数中的对象类型是否该视图模板所需要的对象类型。”@model“语句后面坚决不能跟”;“,如果有这个分号会报错。也会导致运行错误!!