EasyUI的后台界面搭建及极致重构

〇、前言

  要了解一个东西长什么样,至少得让我们能看到,才能提出针对性的见解。所以,为了言之有物,而不是凭空漫谈,我们先从UI说起,后台管理页面的UI我们将使用应用比较普遍的easyui框架。

  以前在用easyui的时候,每个页面都得从0做起,或者不厌其烦地由以前的页面通过“复制-粘贴”的方式来修改,久页久之,就会造成页面庞大且难以维护。其实,前端的html,javascript代码与后端的代码是一样的,通过一定的组织,把重复的代码抽离出来,同样也通过达到很好的复用率。而MVC的天生的Layout布局与分布视图(Partial View),就是对重复代码抽离的需求有很好的支持。

一、目录

二、EasyUI-Layout布局

_Layout.cshtml

  MVC的布局,最先当然是作为根视图存在的_Layout.cshtml了,_Layout.cshtml很简单,只是负责一些样式文件和公共脚本的引用。开发阶段,先使用绝对地址进行引用,发布的时候再进行压缩代码的考虑。

  在_Layout.cshtml中,除了必需的 @RenderBody() ,还定义了两个Section,分别为负责引用子级视图样式的 @RenderSection("header", false) 和负责引用子级视图脚本的 @RenderSection("footer", false)

 1 @{
2 Layout = null;
3 }
4 <!DOCTYPE html>
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8 <meta name="viewport" content="width=device-width, initial-scale=1.0">
9 <title>@ViewBag.Title - OSharp管理系统</title>
10 <link href="/Content/themes/gray/easyui.css" rel="stylesheet" />
11 <link href="/Content/themes/icon.css" rel="stylesheet" />
12 <link href="/Content/osharp-icons.css" rel="stylesheet" />
13 <link href="/Content/osharp-admin.css" rel="stylesheet"/>
14 @RenderSection("header", false)
15 </head>
16 <body>
17 @RenderBody()
18 <script src="/Scripts/jquery-1.11.1.js" type="text/javascript"></script>
19 <script src="/Scripts/jquery.easyui-1.4.1.js" type="text/javascript"></script>
20 <script src="/Scripts/locale/easyui-lang-zh_CN.js" type="text/javascript"></script>
21 <script src="/Scripts/json2.js" type="text/javascript"></script>
22 <script src="/Scripts/osharp.global.js" type="text/javascript"></script>
23 <script src="/Scripts/osharp.easyui.js" type="text/javascript"></script>
24 <script src="/Scripts/osharp.data.js" type="text/javascript"></script>
25 @RenderSection("footer", false)
26 </body>
27 </html>

后台的EasyUI-Layout布局

  一般来说,后台管理页面都是这样一个布局方式:

  1. 上边一个顶栏
  2. 左边一个手风琴或树形的导航栏
  3. 中间是一个由iframe加载具体内容页的多选项卡tab页面

  这样,就要用到easyui的easyui-layout来做整体布局,左边的导航栏使用easyui-accordion,右边加载内容页的多选项卡使用easyui-tabs。easyui的布局在网上也很普遍,具体的就不说了,完整代码如下:

 

  效果如下:

  

左导航数据加载

  由上面的代码可知,左边导航菜单,完全是由JS解析后端返回的JSON数据来构建,使用后端来返回数据,而不是在前端构建菜单数据,主要是便于将来进行权限控制,后端可以根据当前用户的权限返回特定的菜单数据。后端代码如下:

 

  上面的代码中,添加了一个 [AjaxOnly],作用标记此方法只允许AJAX的调用方式,拦截非Ajax调用,在数据安全上能起到一定的作用。

 1 /// <summary>
2 /// 限制当前功能只允许以Ajax的方式来访问
3 /// </summary>
4 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
5 public class AjaxOnlyAttribute : ActionFilterAttribute
6 {
7 /// <summary>
8 /// Called before an action method executes.
9 /// </summary>
10 /// <param name="filterContext">The filter context.</param>
11 public override void OnActionExecuting(ActionExecutingContext filterContext)
12 {
13 if (!filterContext.HttpContext.Request.IsAjaxRequest())
14 {
15 filterContext.Result = new ContentResult
16 {
17 Content = Resources.Mvc_ActionAttribute_AjaxOnlyMessage
18 };
19 }
20 }
21 }

  打上此自定义属性后,如果使用非AJAX的方式来调用上面的GetNavData代码,无法得到返回的JSON数据

  

  正确解析返回数据后,构建导航菜单,点击菜单后打开相应的选项卡

  

三、EasyUI-datagrid布局

提取父视图(模板)_DataGridLayout.cshtml

  在实践中,我们会发现,大部分 datagrid 的代码组织方式都相似的,不同的只是数据源不同,操作之后提交的URL不同。为了减少重复代码,提高代码的复用率,我们可以把共同的代码提取出来,而MVC的 Layout 又刚好是支持嵌套的,那么,类似于前面的 _Layout.cshtml,我们可以提取一个datagrid的共同父视图 _DataGridLayout.cshtml。

  _DataGridLayout.cshtml 的提取原理如下:

  1. javascript 的变量均是全局变量,并且是有前后顺序的,就可以按需要进行重新赋值
  2. 在 父视图(_Layout)中初始化 javascript变量,并在适当的位置(变量真正使用之前)向 子视图(Partial View)开放 RenderSection
  3. 子视图(Partial View)按需要对 父视图(_Layout)中定义的 javascript变量 进行重新赋值
  4. 正在的运算逻辑运算的时候,使用的就是重新赋值的新值了,以达到复用 Layout 的目的
  5. 父视图中需要的 C# 变量,通过在子视图中定义 ViewBag 传递过去,比如dom元素的id,数据操作的URL等等

  根据 easyui-datagrid 的常用变量及上面的原理,定义的 _DataGridLayout.cshtml 大致结构如下,请结合注释进行理解:

 1 @{
2 Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
3 string toolbarItem = ViewBag.ToolbarItem ?? "add,edit,save,cancel,delete";
4 }
5 @section header
6 {
7 <style type="text/css">
8 html { font-family: sans-serif; }
9 .datagrid-header-inner { font-weight: bold; }
10 </style>
11 }
12 @section footer
13 {
14 @*这里进行变量初始化*@
15 <script type="text/javascript">
16 //定义及初始化变量
17 var rownumbers = true, singleSelect = false, ctrlSelect = true, multiSort = false, pageSize = 25;
18 var grid, frozenColumns = [[]], columns = [[]], ...
19
20 //前置逻辑,将在构造datagrid之前执行
21 var startfunction = function() { };
22 //后置逻辑,将在构造datagrid之后执行
23 var endfunction = function() { };
24
25 </script>
26
27 @*开放一个Section,让子视图(Partial View)可以插入代码,对上面定义的变量进行重新赋值。*@
28 @RenderSection("customScript", true)
29
30 @*这里才正在执行业务逻辑*@
31 <script type="text/javascript">
32 $(function () {
33 //执行前置逻辑
34 startfunction();
35
36 //构造 datagrid
37 grid = $("#grid-@ViewBag.GridId").datagrid({
38 title: "@ViewBag.Title",
39 fit: true,
40 frozenColumns: frozenColumns,
41 columns: columns,
42 fitColumns: false,
43 url: "@ViewBag.GridDataUrl",
44 ...
45 });
46
47 //执行后置逻辑
48 endfunction();
49 });
50 </script>
51 }
52 @* 后台还有可能有需要执行的逻辑,开放一个Section *@
53 @RenderSection("endScript", false)
54 }
55 @* datagrid 前面有可能需要插入html,开放一个Section *@
56 @RenderSection("headHtml", false)
57 <div id="grid-@ViewBag.GridId"></div>
58 @* datagrid 后面有可能需要插入html,开放一个Section *@
59 @RenderSection("footHtml", false)

  结合实际需求,OSharp中定义的一个可用的 _DataGridLayout.cshtml 如下,可以根据需求进行更改:

 

实例应用

  OSharp.Web组件中,定义了一个专用于返回表格数据的类,表格只需要行数据与总行数

 1 /// <summary>
2 /// 列表数据,封装列表的行数据与总记录数
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 public class GridData<T>
6 {
7 public GridData()
8 : this(new List<T>(), 0)
9 { }
10
11 public GridData(IEnumerable<T> rows, int total)
12 {
13 Rows = rows;
14 Total = total;
15 }
16
17 /// <summary>
18 /// 获取或设置 行数据
19 /// </summary>
20 public IEnumerable<T> Rows { get; set; }
21
22 /// <summary>
23 /// 获取或设置 数据行数
24 /// </summary>
25 public int Total { get; set; }
26 }

  通过这个类,就可以向easyui返回数据了,如下:

 1 [AjaxOnly]
2 public ActionResult GridData()
3 {
4 List<object>data =new List<object>();
5 for (int i = 1; i <= 20; i++)
6 {
7 var item = new { Id = i, Name = "UserName" + i, NickName = "用户" + i, IsDeleted = false, CreatedTime = DateTime.Now.AddMinutes(i) };
8 data.Add(item);
9 }
10 return Json(new GridData<object>(data, data.Count), JsonRequestBehavior.AllowGet);
11 }

  有了前面定义的 datagrid 父视图 _DataGridLayout.cshtml,用户列表(Views\Users\Index.cshtml)的代码就是如此的简单,仅仅需要把columns重新赋值而已

 1 @{
2 ViewBag.Title = "用户信息列表";
3 Layout = "~/Areas/Admin/Views/Shared/_DataGridLayout.cshtml";
4
5 ViewBag.GridId = "users";
6 ViewBag.GridDataUrl = Url.Action("GridData");
7 }
8 @section customScript
9 {
10 <script type="text/javascript">
11 columns = [[
12 { field: "Id", title: "编号", width: 40, halign: "center", align: "right", sortable: true },
13 { field: "Name", title: "用户名", width: 150, sortable: true },
14 { field: "NickName", title: "用户昵称", width: 150, sortable: true },
15 { field: "IsDeleted", title: "已删除", width: 80, sortable: true, align: "center", formatter: formatBoolean },
16 { field: "CreatedTime", title: "创建时间", width: 150, halign: "center", align: "center", sortable: true, formatter: function (value) { return $.osharp.tools.formatDate(value); } }
17 ]];
18 </script>
19 }

  这样,便可以运行出用户列表的结果,如下

  

  比如添加一个角色信息列表,视图(Views\Roles\Index.cshtml)也同用户列表一样,简单到极致:

 1 @{
2 ViewBag.Title = "角色信息列表";
3 Layout = "~/Areas/Admin/Views/Shared/_DataGridLayout.cshtml";
4
5 ViewBag.GridId = "roles";
6 ViewBag.GridDataUrl = Url.Action("GridData");
7 }
8 @section customScript
9 {
10 <script type="text/javascript">
11 columns = [[
12 { field: "Id", title: "编号", width: 40, halign: "center", align: "right", sortable: true },
13 { field: "Name", title: "角色名", width: 150, sortable: true },
14 { field: "Remark", title: "角色描述", width: 150, sortable: true },
15 { field: "CreatedTime", title: "创建时间", width: 150, halign: "center", align: "center", sortable: true, formatter: function (value) { return $.osharp.tools.formatDate(value); } }
16 ]];
17 </script>
18 }

  运行效果:

  

  就是这样,多动脑,多总结,前端的代码也同样能像后台C#代码一样重构,重构到极致。

  未完待续。。。

四、开源说明

 (一)github.com

  OSharp项目已在github.com上开源,地址为:https://github.com/i66soft/osharp,欢迎阅读代码,欢迎 Fork,如果您认同 OSharp 项目的思想,欢迎参与 OSharp 项目的开发。

  在Visual Studio 2013中,可直接获取 OSharp 的最新源代码,获取方式如下,地址为:https://github.com/i66soft/osharp.git

  

 (二)nuget

  OSharp的相关类库已经发布到nuget上,欢迎试用,直接在nuget上搜索 “osharp” 关键字即可找到
  

系列导航

    1. 【开源】OSharp框架解说系列(1):总体设计
    2. 【开源】OSharp框架解说系列(2):从后台UI说起-EasyUI的后台界面搭建
    3. 【开源】OSharp框架解说系列(2.2):EasyUI复杂布局及数据操作

EasyUI的后台界面的更多相关文章

  1. 【开源】OSharp框架解说系列(2.1):EasyUI的后台界面搭建及极致重构

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  2. 第二百三十节,jQuery EasyUI,后台管理界面---后台管理

    jQuery EasyUI,后台管理界面---后台管理 一,admin.php,后台管理界面 <?php session_start(); if (!isset($_SESSION['admin ...

  3. 第二百二十九节,jQuery EasyUI,后台管理界面---后台登录

    jQuery EasyUI,后台管理界面---后台登录 登录原理图 一,login.php,登录界面 <!DOCTYPE html> <html> <head> & ...

  4. 【SSH网上商城项目实战03】使用EasyUI搭建后台页面框架

    转自:https://blog.csdn.net/eson_15/article/details/51312490 前面两节,我们整合了SSH并且抽取了service和action部分的接口,可以说基 ...

  5. 【分享】国外后台界面HTML源码 [免费]

    国外后台界面HTML模版下载,里面的文字是英文的,不过可以修改成中文,带有数据统计界面和曲线图,本套模板相对完整,在主界面上点击那些菜单,都可以点开二级页面,希望对搞代码的程序员,对不擅长美工的朋友提 ...

  6. 50个令人惊奇的jQuery插件(对话框和表单篇)及免费的响应式bootstrap管理员后台界面主题 - Charisma

    http://www.woiweb.net/50-amazing-jquery-plugins.html 多文件文件下载 免费的响应式bootstrap管理员后台界面主题 – Charisma htt ...

  7. DoNet开源项目-基于jQuery EasyUI的后台管理系统

    博主在业余时间开发了一个简单的后台管理系统,其中用到了 jQuery EasyUI 框架,上次分享过系统布局,参考文章:jQuery EasyUI 后台管理系统布局分享,目前已完成系统的整体框架的搭建 ...

  8. solr后台界面介绍——(十一)

    1.加一个collection的方法 复制solr-home下的collection1,修改名字为collection2.并且修改collection2文件夹中配置文件core.properties中 ...

  9. Html/CSS 示例演练 图书馆后台界面

    示例演练(html css javascript) --制作图书馆后台界面 1. 成品图

随机推荐

  1. Python标准库09 当前进程信息 (部分os包)

    原文:Python标准库09 当前进程信息 (部分os包) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们在Linux的概念 ...

  2. C++ 静态static 变量在 cocos2d-x 里面使用误区

    void Cms::showMonster(CCArray* monsterArray,int type) { <span style="color:#ff0000;"> ...

  3. 准确率和召回率(precision&amp;recall)

    在机器学习.推荐系统.信息检索.自然语言处理.多媒体视觉等领域,常常会用到准确率(precision).召回率(recall).F-measure.F1-score 来评价算法的准确性. 一.准确率和 ...

  4. 编写高质量JavaScript代码绳之以法(The Essentials of Writing High Quality JavaScript)翻译

    原文:The Essentials of Writing High Quality JavaScript 才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<Java ...

  5. Unity项目优化--开发项目的小经验

    原文地址:http://blog.csdn.net/liang_704959721/article/details/8548619 我们主要使用 3dsmax2010 进行制作,输出 FBX的类型导入 ...

  6. YouTube图片幻灯片分享技巧

    以前,您将使用的Windows Movie Maker或Picasa的工具,如缝合的图像文件转换成视频上传到YouTube.然而,添美的小编分享了她的技巧,你可以创建一个图片直接进入YouTube的视 ...

  7. Visual studio 2013 bug:visual studio no editoroptiondefinition export found for the given option nam

    昨天VS 2013打开项目,双击cs当文件,下面出现bug. Google没有理由.最后,在刚刚好清理C磁盘缓存用户文件夹. 然后就OK了. 详细的路径是:C:\Users\{当前用户}\AppDat ...

  8. Android FM学习中的模块 FM启动过程

    最近的研究FM模,FM是一家值我正在学习模块.什么可以从上层中可以看出. 上层是FM按钮的操作和界面显示,因此调用到FM来实现广播收听的功能. 看看Fm启动流程:例如以下图: 先进入FMRadio.j ...

  9. GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)[转]

    WGS-84:是国际标准,GPS坐标(Google Earth使用.或者GPS模块)GCJ-02:中国坐标偏移标准,Google Map.高德.腾讯使用BD-09:百度坐标偏移标准,Baidu Map ...

  10. js之with

    网上找资料的时候看到有js代码里出现了大量的with语句,有点好奇,这里做下总结: 1)简要说明         with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性. ...