DataTable源码分析(二)
=====================
DataTable函数分析
----------------
DataTable作为整个插件的入口,完成了整个表格的数据初始化、表格展现等等操作。本人采用比较笨的办法,逐行的研究这个函数,看看这里究竟做了什么。当然,由于本人对于JavaScript也是一知半解,很多时候,需要配合了解JavaScript的语法才能真正了解具体的函数用法,下面也会一一讲解。
###总体概览
函数从代码的90多行开始,一直到1300多行结束,看起来不算长的函数内部,其实调用了很多函数外部定义的api函数,这些函数在DataTable()外部定义,以_fn开头,整个源码包主要就是由这些函数组成的。

而DataTable()函数又由两部分组成:前半部分主要是定义DataTable的函数,这些函数定义为this.函数名,例如:
```
this.fnDeleteRow = function( target, callback, redraw )
{
...
}
```
看到这样的定义方法,结合DataTable源码分析(一)中描述的,通过页面的元素(table)的JQuery对象来调用DataTable()函数,这时,函数中的this就指向了页面元素(table)的JQuery对象,这其实也就是向这个页面的元素(table)的JQuery对象中,添加了方法。这样,就可以通过下面的方法来访问DataTable函数中定义的这些方法了,也就是api
```
$('#exampe').fnDeleteRow(...)
```
DataTable()函数在最后返回了this,也就是说我们也可以通过下面的方法来调用这些api函数
```
var oTable = $('#example').dataTable();
oTable.fnDeleteRow(...)
```
这也是每个函数开始的注释中给出的用法示例。这样看来,我们也可以用这样的办法来自定义我们自己的插件的api,使我们的插件附加在原生的html元素上,却又有很多自定义的方法,是不是很cool?

写到这里,想来上面的第一种调用api的方法,应该是有问题的,因为JQuery每次通过选择器得到对象时,都是一个新的实例,而这里的this是把函数定义到了当前的实例,所以执行过dataTable()函数后,再使用$('#example'),得到的是一个新的实例,也就不具备上面说的api函数了,调用会失败。

DataTable()函数的下半部分是实际执行的内容从849行左右开始,直到函数结束,这里完成了数据的初始化,和页面的展示等功能
###DataTable函数的执行
略过DataTable对api函数的定义,下面重点分析DataTable()函数的执行过程,看看这个函数是怎么把一个表格呈现出来的。

开始,程序定义了一些变量,这里引用了_ext,这个对象定义在代码的13827行左右。
```
DataTable.ext = _ext = {
...
}
```
这里定义了很多属性,同时这个属性也被定义在DataTable.ext上。这里从单词的含义可以理解为扩展的属性和方法,或是是插件,这里暂时略过具体的内容。

之后,对于this进行遍历,这个遍历是考虑了this下面包含多个table的情况,也就是说明这个插件支持一次对多个table进行操作,而不仅仅是针对一个table的管理。

接下来,是在循环遍历中的代码。程序首先对当前对象的节点名字进行了判断,如果不是‘table’函数直接返回。然后,调用_fnCompatOpts和_fnCamelToHungarian对defaults和defaults.column进行处理。

这里的_fnCompatOpts和_fnCamelToHungarian是干什么的?去查源码就会发现,_fnCompatOpts函数是用来将default中一部分属性改个名字,然后再加入default中。这其实就是给对象的属性建立了一个别名,从注释和函数名来看,这个据说是为了保证向后的兼容,可能是以后的版本中会使用新的属性名称吧。

_fnCamelToHungarian是一个更加诡异的函数,他的作用是对传入参数的属性名进行修改,如果是驼峰表示法就改成匈牙利表示法。这里的驼峰和匈牙利也是这个插件里的一种说法,本身插件内部的命名规则也不太属于标准的匈牙利表示法。所以,我们说的驼峰和匈牙利都以插件代码的表示法为依据,代码中的驼峰就是形如“tableBody”这样的变量名,而匈牙利则是“oTableBody”,其中的o代表了变量的类型是一个对象(object)。也就是说,匈牙利表示法用一个前缀来表示变量或熟悉的类型,而驼峰则没有类型的前缀,只是以小写字母开始,之后的代词首字母大写。这个函数会根据传入的第一个参数的匈牙利表示法的属性名,建立一个驼峰表示法的对应表。例如,一个属性名是aoDataTable(表示对象数组),则在对应表中就是一个dataTables,aoDataTable的对应关系(key,value).然后再对比第二个参数的属性,如果属性在这个对应表中,匹配到了key,说明这个属性是一个驼峰表示法定义的属性,这时,在第二个参数对象中增加一个属性,是这个驼峰表示法对应的匈牙利表示法的属性,值仍然是本属性的值。这个函数其实是把第一参数作为模板,来转换第二参数,也就是只能转换第一个参数中包含的属性。

这里的两个函数的调用是,先调用_fnCompatOpts,然后调用_fnCamelToHungarian。例如,先调用``_fnCompatOpts( defaults );``,然后调用``_fnCamelToHungarian( defaults, defaults, true );``。为什么在_fnCamelToHungarian``( defaults, defaults, true );传入相同的参数?我想可能是由于``_fnCompatOpts( defaults );``向defaults中增加了新的属性,调用_fnCamelToHungarian函数尽量使新增加的属性,具有匈牙利表示法的别名。
setting
还要注意的一点是,参数defaults和defaults.column这个是在插件中定义的对象,内部包含了大量的预设的值,用来在创建表格式作为默认的设置。

然后,程序继续调用了``_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );``,这里关键的是通过$.extend将定义在table上的"data-"属性合并到oInit中,注意**oInit**是在表格创建中非常重要的一个对象,包含了所有的初始化信息。这里首先把附件在table上的用户自定义的数据合并到**oInit**,由于通常我们不会再table上设置“data-”属性,所以到目前为止,**oInit**内容还是{}。

揭下来,程序对于DataTable对象定义的另外一个属性**setting**进行处理,主要是用来判断重复初始化的情况,由于我们大多数情况是第一次初始化,所以当前的**DataTable.setting**为空,不会进入后面的循环。

再往下,是对sId的判断,sId在前面的代码中得到,就是table的id属性,如果为空,程序会生成一个“DataTables_Table_”开头的id,设置到table上。

DataTable源码分析(二)的更多相关文章

  1. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  2. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  3. Tomcat源码分析二:先看看Tomcat的整体架构

    Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...

  4. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  5. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  6. 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>

    目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...

  7. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

  8. spring源码分析(二)Aop

    创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...

  9. ConcurrenHashMap源码分析(二)

    本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...

随机推荐

  1. Linux学习之Linux目录及文件系统

    以往的 Windows 一直是以存储介质为主的,主要以盘符(C 盘,D 盘...)及分区来实现文件管理,然后之下才是目录,目录就显得不是那么重要,除系统文件之外的用户文件放在任何地方任何目录也是没有多 ...

  2. wpf的无边框窗体透明

    本人做了3年的winform,来了新的工作,需要使用wpf.对于wpf,本人小白一个.说的不对的地方,请大家多多指导.... 今天先从wpf的窗体属性开始说起! 需要做的项目功能大概和电脑桌面类似,需 ...

  3. 自定义view(二)

    这里是自定义view(二),上一篇关于自定义view的一些基本知识,比如说自定义view的步骤.会涉及到哪些函数以及如何实现自定义属性,同时实现了一个很基础的自定义控件,一个自定义的计时器,需要看的人 ...

  4. Laravel中间件

    先谈一谈中间件的使用场景,比如路由转到一张页面,我们需要记录用户的cookie,或者检测用户的访问权限,这些操作如果全写在控制器里是不合适的,因为随着业务的扩充,控制器里的业务逻辑会越来越臃肿,难以维 ...

  5. SQL Server-聚焦NOLOCK、UPDLOCK、HOLDLOCK、READPAST你弄懂多少?(三十四)

    前言 时间流逝比较快,博主也在快马加鞭学习SQL Server,下班回来再晚也不忘记更新下博客,时间挤挤总会有的,现在的努力求的是未来所谓的安稳,每学一门为的是深度而不是广度,求的是知识自成体系而不是 ...

  6. node.js爬虫爬取拉勾网职位信息

    简介 用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招聘信息,共爬取了北京.上海.广州.深圳.杭州.西安.成都7个城市的数据,分别以前端.PHP.java.c++.python.Androi ...

  7. 获取3个月前的时间(获取某一天的时间 NSDate)

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; ...

  8. Python--校园网爬虫记

    查成绩,算分数,每年的综合测评都是个固定的过程,作为软件开发者,这些过程当然可以交给代码去做,通过脚本进行网络请求获取数据,然后直接进行计算得到基础分直接填表就好了,查成绩再手动计算既容易出错也繁琐, ...

  9. Spring-Mybatis配置多数据源

    可以参考: http://www.cnblogs.com/ityouknow/p/6102399.html 需要一个DatabaseConfiguration类,实现 TransactionManag ...

  10. centos6.7编译安装mysql5.7.17

    centos6.7编译安装mysql5.7.17 2017-03-24 09:57:15 提示:mysql5.7.17和之前5.56以前的版本安装不一样,需要用cmake 另外,看本文档的mysql编 ...