Gridx入门

原创英文版链接:https://github.com/evanhw/gridx/wiki/Introduction-to-Gridx

虽然同样都是基于Dojo store, 但与DataGrid/EnhancedGrid相比,Gridx有一套完全不同的架构。它有以下特点:

  1. Gridx采用了一套与UI无关的内核来处理所有的表格数据的逻辑操作。
  2. Gridx采用了一套灵活的模块化系统,它与基于plugin的EnhancedGrid架构不同,这种模块化架构不仅能提配置各种表格特性的灵活性,并且当一些功能不使用时,能够减少运行代码的大小。
  3. Gridx开发了一套简洁直接的API,使得各模块之间实现真正的松耦合。

本文将简要介绍如何使用Gridx进行开发。现在Gridx仍处于开发阶段,一些API和实现的细节仍有可能调整。但它的基本用法和架构已经稳定。感兴趣的童鞋不妨一试。

1. 创建

假设我们有如下HTML页面:


首先,要引入Gridx的CSS:


目前Gridx只支持Claro主题,如果要在RTL模式下运行,请用如下代码来引入:

我们必须“请求require” 的JavaScript 模块是:

  1. 一种Store类型,例如:dojo/store/Memory
  2. gridx/Grid
  3. gridx/core/model/cache/Sync (用于客户端store) or gridx/core/model/cache/Async (用于服务器端 store)

假设我们要创建基于dojo/store/Memory的grid,那么我们需要如下代码:


与DataGrid/EnhancedGrid类似,我们需要定义列结构:


OK,万事俱备,现在我们可以创建一个简单的grid了:


Gridx继承于dijit._WidgetBase, 因此它支持所有widget的基本特性。

以上创建的grid是一个最基本但可用的grid。我们可以灵活的给它加上很多模块,并且这些模块独立工作,它们之间不会相互冲突。下面一节我们将介绍如何实现这一点。

2. 基本API和API对象

Gridx引入了如下API对象:rows,columns,和cells,可以通过这些对象来操作API。

例如我们可以用如下代码来获得第2行的id:

获得位于第1行第2列格子的数据:

获得第3列的name属性:

以上方法中的grid.row(), grid.cell() 和 grid.column()就是我们所说的API对象。它们只是一套API的容器,本身是没有状态的。因此,我们如果想获得一个cell对象,可用如下代码:

然后我们改变此cell中的data,再调用:

则data2中就得到更新过的cell data,而不是data1的值。

如果想要获得列名组成的数组,我们可以使用一个更好的API:

columns()和rows()方法返回的是API对象数组。这两个方法同样接受指定范围的参数。例如,如果你只想获得前3列的列名,就可以写成:

如果需要从第2列开始的两列列名,则可以写成:
获得从第3列开始的后面所有列名:

返回的数组可以用各种非常有用的数组函数才操作,例如map,filter,forEach,some 以及 every。

我们可以使用API对象来调用模块提供的更多方法。例如,如果加载了sort模块,我们可以这样写:

下面一些其它常用的API方法:

模块提供了模块API,它们在底层整合,因此不必担心模块之间会相互影响造成冲突。下一节我们将具体介绍更多关于模块API的内容。

3. 模块

几乎所有的Gridx UI特性都是以模块的方式实现,包括表头,表格体(所有行), 滚动条(横向和纵向滚动条)等。不过这些是核心模块,缺省状态下是自动加载的。非核心模块与EnhancedGrid的插件“plugin”类似,可以根据需要选择要加载的模块。

理论上说,一个Gridx模块可以只是一个dojo类,并可以放在任何地方。但通常情况下,Gridx模块继承自gridx/core/_Module 并且放在gridx/modules目录下。如果要在一个grid实例中添加一个模块,首先我们需要“请求”该模块的源代码,然后在创建grid的时候声明之。

为一个grid实例声明模块只需要将所有模块类放在一个数组中。这种声明方法比之EnhancedGrid的plugin更加简单明了。因为相对于隐式使用的类,例如string类,被“请求”的模块类(Sort和ColumnResizer) 是显式地使用的。但是当我们想要传递一些初始参数,则需写成:

如果你感觉这种写法不够酷,那么还有另外一种写法,将其声明成grid的参数

如果一个模块参数声明成grid的参数,它必须以模块名开头,这样不同模块的参数才不会相互冲突。

Gridx模块被设计成可替换的。这意味着如果你不喜欢某一个模块,你完全可以实现你自己的模块,同时不需要太担心它是否会对grid的其他部分或者该模块之前的实现产生不可预料的影响。你只需要遵循该模块所有的API,这样你的实现就能很好的与其他模块无缝合作。这里的“API集合”是用模块名来标识的。是的,跟声明grid参数一样将模块名作为前缀。例如,模块 gridx/modules/select/Row/ 名为“selectRow”, 这意味着它实现了所有“selectRow”的API。现有另一模块 gridx/modules/extendedSelect/Row, 它也名为“selectRow”, 这意味着该模块实现了同样的API集合。因此当另外一个模块依赖于行选择的特性,它只需要依赖于这个API集合,而不是某一个特定的实现。


有时候,模块也可能依赖于其他模块。例如,UI模块“paginationBar” 依赖于一个非UI模块“pagination”。 因此当声明PaginationBar模块时,我们也需要请求Paginatioin模块。但我们不需要在创建grid时声明Pagination模块,只是“请求”这个关联模块的源代码即可。如果没有请求这个关联模块,我们就会在控制台中得到如下出错信息,并且该grid很可能不会正确的显示。

这看起来似乎有点不方便。因为在EnhancedGrid中,所有关联的插件都是自动加载的。但为了提高灵活性,这种做法是不可避免的。因为在EnhancedGrid中,如果一个插件已经自动被其他插件请求了,我们就无法轻松的替换这个插件的实现。另一个好处是,这种做法可以减少一些不可见的源代码加载,从而提高效率。

几乎所有的模块都可以通过grid对象来直接访问。例如:

在这种方式下,每个模块都有自己的命名空间,因此他们不会相互冲突。

一个模块可以选择暴露哪些API给grid,已经暴露哪些API给API对象(row/column/cell)。请注意模块名只是暴露给grid的API的标识,这样就可以减少依赖性,并且提高代码的可维护性。

以下是目前支持的非核心模块列表。更多精彩细节我们会在将来的博文中介绍。

你可能感兴趣的:(grid)