Gridx入门

33 篇文章 1 订阅

原创英文版链接: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页面:

[html]  view plain copy
  1. <html>  
  2. <head>  
  3.     <title>Gridx Demo</title>  
  4.     <script type="text/javascript" src="dojo/dojo.js" data-dojo-config="async: true"></script>  
  5. </head>  
  6. <body>  
  7.     <!-- We'd like to show a grid here -->  
  8.     <div id="gridNode" style="width: 400px; height: 300px;"></div>  
  9. </body>  
  10. </html>  

首先,要引入Gridx的CSS:

[html]  view plain copy
  1. <link rel="stylesheet" href="gridx/resources/claro/Gridx.css" />  

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

[html]  view plain copy
  1. <link rel="stylesheet" href="gridx/resources/claro/Gridx_rtl.css" />  

我们必须“请求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,那么我们需要如下代码:

[javascript]  view plain copy
  1. require([  
  2.     'dojo/store/Memory',  
  3.     'gridx/Grid',  
  4.     'gridx/core/model/cache/Sync'  
  5. ], function(Store, Grid, Cache){  
  6.     var store = new Store({  
  7.         data: [  
  8.             {id: 1, title: 'Hey There', artist: 'Bette Midler'},  
  9.             {id: 2, title: 'Love or Confusion', artist: 'Jimi Hendrix'},  
  10.             {id: 3, title: 'Sugar Street', artist: 'Andy Narell'}  
  11.         ]  
  12.     });  
  13.     ......  
  14. });  

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

[javascript]  view plain copy
  1. var columns = [  
  2.     {field: 'id', name: 'Identity'},  
  3.     {field: 'title', name: 'Title'},  
  4.     {field: 'artist', name: 'Artist'}  
  5. ];  

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

[javascript]  view plain copy
  1. var grid = new Grid({  
  2.     cacheClass: Cache,  
  3.     store: store,  
  4.     structure: columns  
  5. }, 'gridNode'); //Assume we have a node with id 'gridNode'  
  6. grid.startup();  

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

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

2. 基本API和API对象

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

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

[javascript]  view plain copy
  1. var id = grid.row(1).id;  
获得位于第1行第2列格子的数据:

[javascript]  view plain copy
  1. var data = grid.cell(0, 1).data();  
获得第3列的name属性:

[javascript]  view plain copy
  1. var title = grid.column(2).name();  

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

[html]  view plain copy
  1. var cell = grid.cell(0, 0);  
  2. var data1 = cell.data();  
然后我们改变此cell中的data,再调用:

[javascript]  view plain copy
  1. var data2 = cell.data();  
则data2中就得到更新过的cell data,而不是data1的值。

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

[javascript]  view plain copy
  1. var names = grid.columns().map(function(col){  
  2.     return col.name();  
  3. });  
columns()和rows()方法返回的是API对象数组。这两个方法同样接受指定范围的参数。例如,如果你只想获得前3列的列名,就可以写成:

[javascript]  view plain copy
  1. grid.columns(0, 3);  
如果需要从第2列开始的两列列名,则可以写成:
[javascript]  view plain copy
  1. grid.columns(1, 2);  
获得从第3列开始的后面所有列名:

[javascript]  view plain copy
  1. grid.columns(2);  
返回的数组可以用各种非常有用的数组函数才操作,例如map,filter,forEach,some 以及 every。

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

[javascript]  view plain copy
  1. grid.column(0).sort();  
下面一些其它常用的API方法:

[javascript]  view plain copy
  1. grid.setColumns(columnStructure);       //Reset the column structure  
  2.    grid.setStore(store);       //Reset store  
  3.    grid.columnCount(); //Faster than grid.columns().length;  
  4.    grid.rowCount();    //Faster than grid.rows().length;  
  5.    grid.resize();  //This is what layout widgets (containers) need.  
模块提供了模块API,它们在底层整合,因此不必担心模块之间会相互影响造成冲突。下一节我们将具体介绍更多关于模块API的内容。

3. 模块

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

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

[javascript]  view plain copy
  1. require([  
  2.     'dojo/store/Memory',  
  3.     'gridx/Grid',  
  4.     'gridx/core/model/cache/Sync',  
  5.     'gridx/modules/SingleSort'//Require module source code  
  6.     'gridx/modules/ColumnResizer'   //Require module source code  
  7. ], function(Store, Grid, Cache, Sort, ColumnResizer){  
  8.     ......  
  9.     var grid = new Grid({  
  10.         cacheClass: Cache,  
  11.         store: store,  
  12.         structure: columns,  
  13.         modules: [  
  14.             Sort,       //Declare modules in a grid instance  
  15.             ColumnResizer   //Declare modules in a grid instance  
  16.         ]  
  17.     });  
  18. });  
为一个grid实例声明模块只需要将所有模块类放在一个数组中。这种声明方法比之EnhancedGrid的plugin更加简单明了。因为相对于隐式使用的类,例如string类,被“请求”的模块类(Sort和ColumnResizer) 是显式地使用的。但是当我们想要传递一些初始参数,则需写成:

[javascript]  view plain copy
  1. modules: [  
  2.        {  
  3.            moduleClass: ColumnResizer,  
  4.            detectWidth: 10  
  5.        },  
  6.        ......  
  7.    ]  
如果你感觉这种写法不够酷,那么还有另外一种写法,将其声明成grid的参数

[javascript]  view plain copy
  1. var grid = new Grid({  
  2.        ......  
  3.        modules: [  
  4.            ColumnResizer  
  5.        ],  
  6.        columnResizerDetectWidth: 10  
  7.    });  
如果一个模块参数声明成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很可能不会正确的显示。

[javascript]  view plain copy
  1. Error: Forced/Required Dependent Module 'pagination' is NOT Found for 'paginationBar'  

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

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

[javascript]  view plain copy
  1. grid.select.row.selectById(rowId);  
  2.     grid.select.column.selectById(colId);  
  3.     grid.sort.sort(colId);  
  4.     grid.columnResizer.setWidth(colId, 100);  
在这种方式下,每个模块都有自己的命名空间,因此他们不会相互冲突。

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

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

[javascript]  view plain copy
  1. 1. CellWidget  
  2. 2. ColumnLock  
  3. 3. ColumnResizer  
  4. 4. Dod  
  5. 5. Edit  
  6. 6. Focus  
  7. 7. IndirectSelect  
  8. 8. Menu  
  9. 9. NestedSort  
  10. 10. Persist  
  11. 11. Printer  
  12. 12. RowHeader  
  13. 13. RowLock  
  14. 14. SingleSort  
  15. 15. SummaryBar  
  16. 16. TitleBar  
  17. 17. Toolbar  
  18. 18. Tree  
  19. 19. VirtualVScroller  
  20. 20. Filter  
  21. 21. FilterBar  
  22. 22. Pagination  
  23. 23. PaginationBar  
  24. 24. move.Row  
  25. 25. move.Column  
  26. 25. dnd.Row  
  27. 26. dnd.Column  
  28. 26. select.Row  
  29. 27. select.Column  
  30. 28. select.Cell  
  31. 29. extendedSelect.Row  
  32. 30. extendedSelect.Column  
  33. 31. extendedSelect.Cell  
  34. 32. exporter.CSV  
  35. 33. exporter.Table  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值