API 插件开发
DataTable 的 API 提供许多 方法,这些方法能用于处理表格并从中收集数据。所需的大量方法均已内置,不过你可能也会发现自己需要创建插件 API 方法来扩展内置的功能。本页面探讨如何为 DataTables 创建插件 API 方法。
在详细介绍如何创建插件方法之前,应该考虑创建何种插件可能更有用
- 使用标准 API 执行常见操作的快捷方式(将多个调用缩短为单个方法)
- 数据摘要方法(求和、平均值、标准差等)
- 功能插件 的表格处理。
DataTables API
在为 DataTables 创建新的 API 方法之前,了解 API 的基本原理 非常重要,特别是链式操作的概念(由于方法会返回自身的实例,因此可以直接在第一个方法的结果中调用其他方法)及其结果设置。
DataTables API 实例就像数组,因为它看起来极像 Javascript 数组并且有许多相同的方法和属性(例如,.length
)- 数组的内容便是该“结果设置”。值得注意的是,从技术层面来讲,API 不完全是数组,只是非常类似,这与 jQuery 类似,你可以在其中使用数组语法访问节点。
实例的结果设置可以是空数组、行、列或单元格索引数组、数据对象或其他任何内容。将会在结果设置中遇到所有类型的数据,其包含内容会极大地取决于你自身的方法。
执行范围
插件 API 方法会在 API 实例的范围内执行 - 例如,this.rows()
会调用 rows()
方法。因此,除了希望执行的 JavaScript 数据和 DOM 处理操作之外,一整套内置的 API 可供自己的方法使用。
此外,API 实例应操作的表格存储在 this.context
参数中。context
参数是 DataTables 设置对象(针对每张表格都是唯一的)的数组 - 它必须是数组,因为 API 是支持多张表格的,并且方法应操作 context
引用的所有表格。
注册新方法
使用 DataTable.Api.register()
静态方法可以注册新的 API 方法。它需要两个参数并且没有返回值
- 输入参数
- 方法名称
- 方法函数
该方法名称是完整的链式表达式)。例如,要添加 rows().sum()
方法,您可以使用该完整字符串 (rows().sum()
)。sum()
方法仅对 rows()
方法(将由 DataTables API 处理器自动添加)的结果可用。还要将 sum()
视为“顶级方法”,它对任何 API 实例可用,与它的链无关。
该方法函数是描述插件逻辑的 function
。如上所述,它在 API 实例的作用域内执行。此外,它可以返回任何值(包括用于链接的实例,如果没有预期其他返回值),并且将接受您的方法所需的任何参数。
示例
让我们考虑两个示例来说明这些要点。第一个 sum()
将成为一个顶级方法,它将简单地对结果集中的数据求和并返回它。第二个将附加到 rows()
方法,并提供向选中行添加类别的能力。它将返回用于链的实例。
sum()
sum()
方法实际上非常简单 - 我们循环遍历结果集中的数据,简单地全部相加并返回该值。最终结果是,我们有一个方法,当结果集包含数字数据时,可以使用该方法对数字数据求和 - 例如,从对 columns().data()
的调用。
DataTable.Api.register( 'sum()', function () {
var sum = 0;
for ( var i=0, ien=this.length ; i<ien ; i++ ) {
sum += this[i];
}
return sum;
} );
示例调用
table.column( 2 ).data().sum();
- `table.cells( '.selected', 3 ).data().sum();
rows().addClass()
此示例更加复杂,因为我们需要考虑 API 的多表特性。需要执行的是,我们循环遍历 API 中的每个上下文(即每个表),并对每个上下文的行也进行循环遍历,并在需要时添加类别。
这是最完整的代码
DataTable.Api.register( 'rows().addClass()', function ( klass ) {
var context = this.context;
for ( var i=0, ien=this.length ; i<ien ; i++ ) {
var innerApi = new DataTable.Api( context[i] );
for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
var node = innerApi.row( this[i][j] ).node();
$(node).addClass( klass );
}
}
return this;
} );
请注意,rows()
将使用数组数组填充结果集!每个表有一个内部数组,并且每个内部数组包含该表的索引。在上面的代码中,这意味着 this.context.length === this.length
(即,结果集中针对每个表有一个项目)。
由于在以下形式中循环遍历多个表在 API 中很常见,因此 DataTables 提供一个 iterator
方法来简化该操作。 iterator
会在内部处理双重 for
循环(和其他类型的循环),并向闭包函数提供有关循环的信息。上面的代码可以简化为
DataTable.Api.register( 'rows().addClass()', function ( klass ) {
return this.iterator( 'row', function ( context, index ) {
var node = new DataTable.Api( context ).row( index ).node();
$(node).addClass( klass );
} );
} );
在 DataTables 1.10.3 中,可以进一步简化,因为针对 iterator
的回调方法在 API 实例的作用域中执行,该实例仅在其上下文中包含有问题的表
DataTable.Api.register( 'rows().addClass()', function ( klass ) {
return this.iterator( 'row', function ( context, index ) {
var node = this.row( index ).node();
$(node).addClass( klass );
} );
} );