最近刚加入GUT项目,学习了很多其他同事写的代码,感觉受益匪浅。

在GUT项目中,经常会碰到这样一个问题:动态生成表格,包括从数据库中读取数据,并绑定在表格中,以及从在页面上通过jQuery新增删除表格。如下所示:

在实现过程中,开发人员经常采用如下方式来实现:

1)          在前台,通过js生成表格行的html字符串,然后通过jquery的after方法加到表格底部。

2)          在后台,读取数据库,然后生成表格的html字符串,然后传递给前台渲染

3)          这样做的好处,主要是可以实现无刷新的操作表格的效果

这种实现方式存在如下些问题(当然,个人意见,仅作技术交流^_^):

1)          代码重复。前台写了一遍表格创建的js,后台又写了一遍

2)          字符串拼接。后台创建时,会大量使用字符串的拼接来实现表格的htnl字符串,不仅影响效率,而且不容易debug。比如少了个引号等,不容易找出来。(关于效率问题,因为字符串在.net中是恒定的,所以如果做很多次字符串的拼接,将造成资料的浪费和效率地下)

3)          绑定表格数据与获取表格数据要写很多代码,假设表格有10列字段,就要写关于这10列的数据怎么获取,以及怎么绑定会表格中的。

4)          开发人员经常在.aspx页面中写数据库的访问操作,这样也不符合MVC分离关注点的精神。如果项目换成别的数据库,比如oracle(按照项目的数据量来看,未来不排除换数据库的可能性),那么届时开发人员将需要满项目中数据库相关的语句来修改。

--------------------------------------分割线------------------------------------------

如前所述,可以从如下几个思路来思考:

1)          能否只在页面上编写一些js脚本,来创造表格,而在后台只是提供要创建表格数据即可。也就是说后台获取数据,然后交给前台去调用js函数创建表格。这样就可以避免前后台都写两次的问题了。而且也不会在后台用大量的字符串拼接来创建表格的html字符串。

2)          能否换种方式,不要通过字符串拼接的方式来创建表格?比如jquery.html()?

3)          能否提供一种统一的创建表格,绑定表格,获取表格数据的方法呢?以免每次都要写那么多代码来创建表格。

基于上述思路,我开发了一个demo,实现了用较少的代码动态创建表格,绑定表格数据,获取表格数据,并保存到数据库中。而且代码是可以复用的。

--------------------------------------分割线------------------------------------------

前期准备:

1)          创建数据库test,添加表person

2)          创建Entities层,DAL层,BLL层

Entities层(通过T4模板自动生成)

using System;

using MyBasicLib;

using MyBasicLib.Data.ORMLiteNew;

namespace ATMB.DCMS.Entities

{

/// <summary>

///

/// </summary>

[Serializable]

[Table(TableName="person" ,KeyName="ID")]

public partial class person:BaseTable

{

/// <summary>

///

/// </summary>

public person()

{

}

#region Public Properties

/// <summary>

///

/// </summary>

public  override  String ID

{

set ; get ;

}

/// <summary>

///

/// </summary>

public  String name

{

set ; get ;

}

/// <summary>

///

/// </summary>

public  String age

{

set ; get ;

}

/// <summary>

///

/// </summary>

public  String sex

{

set ; get ;

}

/// <summary>

///

/// </summary>

public  String location

{

set ; get ;

}

#endregion

}

}

DAL层,实现了新增,批量新增,删除,获取所有数据的几个简单的方法

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using ATMB.DCMS.Entities;

using MyBasicLib.Data.ORMLiteNew;

namespace DAL

{

public class PersonDA

{

public void Add(person p)

{

using (var dc = new DataContext())

{

dc.Insert(p);

dc.SubmitChanges();

}

}

public void Add(List<person> ds)

{

using (var dc = new DataContext())

{

foreach(var p in ds)

{

dc.Insert(p);

}

dc.SubmitChanges();

}

}

public void Delete()

{

using (var dc = new DataContext())

{

dc.Delete<person>(p => !SqlMethods.IsNull(p.ID));

dc.SubmitChanges();

}

}

public List<person> GetList()

{

using (var dc = new DataContext())

{

return dc.GetTable<person>().ToList();

}

}

}

}

BLL层

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using ATMB.DCMS.Entities;

using DAL;

namespace BLL

{

public class PersonBLL

{

PersonDA da;

public PersonBLL()

{

da = new PersonDA();

}

public void Add(List<person> ds)

{

da.Delete();

da.Add(ds);

}

public List<person> GetList()

{

return da.GetList();

}

}

}

备注:数据库底层访问使用Linq,换成oledb等其他方式只要修改DAL层就可以了。

3)          通过js实现表格的动态创建

第一步:定义表格

这里有几个地方要注意下:

第一:页面上添加的表格中,我添加了两个tr,一个是显示出来的tr,带有“新增”的图标。另一个是隐藏的,用来作为新增的行的模板。这样,不容易出错,而且避免通过字符串来创建。

第二:显示的tr中,设置了一个叫”TargetTR”的class,这个是用来搜索表格的所有行的,后面会用到。

第三,每个td中,新增了一个tag属性,与数据库表的实际字段对应,用来自动获取和绑定表格数据。

第四,tr模板的每个input的id(或者其他需要替换的属性)都定义为XXX_x,_x后缀是用来替换的。比如新增了一个tr,序号为3,便要替换tr中每个input的_x后缀为_3。诸如此类。

第二步:实现新增和删除表格行的js方法

ChangeAttr实现如下:

changeAttr主要是实现替换input的带_x结尾的属性为具体的序号。

以上实现了在页面上对表格行的新增和删除。通过模板的定义,我们无需在js写新增的tr的html字符串。这样可以最大可能的减少错误发生的可能性。因为字符串的可读性比较差,debug比较难。

接下来,要实现后台获取表格数据,然后通过上述的几个js脚本动态生成表格。

首先介绍下实现的思路

第一步,看下.ashx中的实现

Ashx中的实现很简单,就是根据前台的请求,进行相应的操作,然后返回结果(json)给前台

第二步:前台通过ajax访问.ashx,获取表格数据

Success时,会以json的格式返回表格的数据(比如person的集合),然后前台会解析这个json数据,并创建表格出来。

BindTable的实现很简单,首先看下共有多少条数据,然后多次调用add_tr方法,添加tr。(因为第一个tr是默认存在的,所以只要调用json.length-1次)

接下来便是该功能的核心了,绑定表格的数据。这里只需要调用一个函数就可以了bindTableValue,其实现如下

这个函数可以实现任意表格的数据绑定。完全可以复用。当然还存在些缺陷。本文最后会作以说明。

以上遍实现了从数据库获取值,然后动态绘制表格的过程。整个过程没有针对特定的表格来实现,所以代码是可以复用的。这个实现过程还有个好处是:分离关注点。对于表现层(前台,web层),只关心于根据数据来做相应的展现,而不关心数据是怎么来的(来自于sql,还是oracle?采用何种方式)。而BLL层负责根据用户的请求返回数据。关注于业务逻辑的处理。这样的实现方式,不会在前台写任何的sql语句。代码看起来比较简洁。

最后,实现将修改后的表格数据保存回数据库中。这就比较简单了

当点击保存时,调用save方法。Save方法中的核心是第一句:

getTableValue的实现为:

这样,开发人员同样不用写任何代码,便可以实现数据对象的自动获取。该代码是可以复用的。

--------------------------------------分割线------------------------------------------

总结:

  1. 上文以可复用,可扩展,分离关注点的方式实现了表格的动态绘制,数据的自动绑定和自动获取。而且用户的代码量相较以往减少了非常多。
  2. 自动绑定和获取的方法还存在些不足,因为当前版本的实现只是基于string类型的。未考虑datetime,bool,int等类型。但是根据分离关注点的原则(或者依赖倒置原则),我们同样可以将该部分逻辑分离出来,交给专门处理数据类型的类来处理。然后保持原有的逻辑不变。下来我会继续改进。
  3. 该方法同样适用于表单数据的保存和绑定.
  4. 心得体会:Less Code, Less Copy, More ReUseable, More Flexiable and More OO。

基于jquery的表格动态创建,自动绑定,自动获取值的更多相关文章

  1. js进阶---12-11、jquery如何给动态创建出来的元素绑定事件

    js进阶---12-11.jquery如何给动态创建出来的元素绑定事件 一.总结 一句话总结:通过事件委托的方式,通过on方法 1.on方法在事件绑定的时候,data方式带额外参数时,字符串参数和其它 ...

  2. JS、JQuery和ExtJs动态创建DOM对象

    做了个简单使用JavaScript.JQuery.ExtJs进行DOM对象创建的测试,主要是使用JavaScript.JQuery.ExtJs动态创建Table对象.动态Table数据填充.多选控制. ...

  3. 解决jquery动态创建元素绑定事件失效问题

    存在问题 在我们使用jquery动态创建元素后往往会遇到一些问题,如: 给.button按钮绑定了点击时间,执行alert:(1); 点击事件代码如下: <script>$("# ...

  4. JQuery实现表格动态增加行并对新行添加事件

    实现功能: 通常在编辑表格时表格的行数是不确定的,如果一次增加太多行可能导致页面内容太多,反应变慢:通过此程序实现表格动态增加行,一直保持最下面有多个空白行. 效果: 一:原始页面 二:表1增加新行并 ...

  5. jquery利用appendTo动态创建元素

    动态创建元素可以说是DOM中常做的事情,下面我来介绍在jquery中利用appendTo来动态创建元素,有需要的朋友可参考参考. 当HTML字符串是没有属性的元素是, 内部使用document.cre ...

  6. Webform动态创建删除行及后台取值

    开发过程中经常碰到许多不确定事项,所以有时需要动态生成新的记录,如图所示,点击新增时新增一条参考记录,点击删除时则删除该记录:第一步,创建一个表格,用hidden记录当前最大行数,添加时则只需复制模板 ...

  7. C#后台创建控件并获取值

    前台代码 <form id="form1" runat="server"> <div> <div class="item ...

  8. Jquery 页面元素动态添加后绑定事件丢失方法,非 live

    代码1: 以此方法绑定的input框事件,在通过add按钮后用jquery绑定的事件 alert就会丢失 <input type="button" value="A ...

  9. 基于JQuery的浮动DIV显示提示信息并自动隐藏

    /** * 浮动DIV定时显示提示信息,如操作成功, 失败等 * @param string tips (提示的内容) * @param int height 显示的信息距离浏览器顶部的高度 * @p ...

随机推荐

  1. 第四讲 :hibernate中的session

    hibernate中的session中可以进行增删改差,通过工具类可以得到相关的工具类. 方法概要:  Transaction beginTransaction()开始一个工作单元,得到关联的事务对象 ...

  2. UVa (二分) 11627 Slalom

    题意: 有宽度相同的水平的n个旗门,水平(纵坐标严格递增)滑行的最大速度为Vh(水平速度可以任意调节).然后还有S双滑雪板,每双滑雪板的垂直速度一定. 然后求能通过的滑板鞋的最大速度. 分析: 显然, ...

  3. 【第四篇】说说layer的iframe弹窗给里面的标签赋值的问题

    说到这一篇,真的是颠覆了我的思维. 官方文档,没有介绍这一部分的操作,大致上提了一下. 我的思路是把页面的数据传过去,在iframe弹窗的页面拿到接收到的数据,然后赋值,但是这样就会有个问题, 怎么传 ...

  4. XenServer6.2详细安装步骤

    系统要求 系统要求 XenServer 至少需要两台单独的 x86 物理计算机:一台用作 XenServer 主机,另一台用于运行XenCenter 应用程序. XenServer 主计算机完全专用于 ...

  5. Bitset位图

    位图(bitmap)就是用每一位来存放某种状态,适合于大规模数据但是数据状态又不是很多的情况下,通常来判断数据是否存在.位图的常见应用有两种: 1.存放大规模数据,例如腾讯的面试题,给40亿个unsi ...

  6. javascript对象定义和操作

    //js对象定义有三种方式//js方法定义有三种方式 function fn(){} var fun = function(){} var fun = new function() {} //**** ...

  7. 每天一个Linux命令(7): cp

    cp命令         该命令的功能是将给出的文件或目录拷贝到另一文件或目录中,同MSDOS下的copy命令一样,功能十分强大.         语法: cp [选项] 源文件或目录 目标文件或目录 ...

  8. Linux用户(组)管理

    在linux中系统中,它并不认识帐号名称.它认识的是我们的帐号ID,帐号ID保存在/etc/passwd文件中.我们在登录linux主机时,在输入完帐号和密码时,linux会先查找/etc/passw ...

  9. Spring cron 表达式

    前言: 最近做的项目有用到定时器,每周只在特定时间运行一次,考虑到Spring Task的简单易用性,就果断选择了,我是配置在配置文件里面,没有用注解@Scheduled,推荐配置,注解虽方便,但更改 ...

  10. LA 3635 Pie 派 NWERC 2006

    有 f + 1 个人来分 n 个圆形派,每个人得到的必须是一整块派,而不是几块拼在一起,并且面积要相同.求每个人最多能得到多大面积的派(不必是圆形). 这题很好做,使用二分法就OK. 首先在读取所有派 ...