Gridx 脱离了 DataGrid 的框架,具有高度模块化的设计,使其能适应各种使用场景的需要。大量针对 DataGrid/EnhancedGrid
的问题而做出的设计上的改进使 Gridx 具有更高的稳定性和更好的性能。同时,API 的设计更直观,且难以被误用。本文从如何创建和使用 Gridx 入手介绍了
Gridx 的基本特点和基本用法,目的是让您对 Gridx 有一个基本的了解。

[size=0.76em]准备工作
[size=0.76em]Gridx 是基于 Dojo 的开源项目,在 GitHub
或者其官网都可以下载到源码包。下载解压后将 gridx 文件夹置于与 dojo、dijit 和 dojox 等文件夹同级的目录即可。目前 Gridx 支持
Dojo1.7+。
[size=0.76em]gridx/tests
文件夹中有大量的示例页面,可以从修改这些示例页面开始学习使用 Gridx。
[size=0.76em]回页首
[size=0.76em]创建 Gridx
[size=0.76em]Gridx 继承了
dijit._Widgetbase,因此其创建方式和其他 widget
类似,只是有一些必须指定的参数需要特别说明。
[size=0.76em]选用合适的 store 和
cache
[size=0.76em]Gridx 与 DataGrid 一样,都以 Dojo 的
store 作为数据源。不过,Gridx 需要用户指出所用的 store 是异步的还是同步的。异步 store
通常由服务器端提供数据,向它请求数据时往往需要异步地接收返回数据;而同步 store 的所有数据一般都在客户端,因此所有的请求都能同步完成。异步 store
往往会带来更为复杂的逻辑,因此 Gridx 针对这两种 store 分别进行了优化。但由于无法从 store
本身得知它是否异步,同时为了减小代码量,用户需要将这个信息告知 Gridx。告知的方法是设置 cacheClass
参数:
清单 1. 创建 Gridx 并配置 cacheClass 参数
require([ "gridx/Grid",
"gridx/core/model/cache/Sync", ...... "dojo/domReady!" ],
function(Gridx, Cache, ......){ ...... var grid = new Gridx({
cacheClass: Cache store: store, ...... });
grid.placeAt('gridContainerNode')grid.startup(); });
[size=0.76em]目前 Gridx 有两种 cache
实现:gridx/core/model/cache/Sync 和 gridx/core/model/cache/Async,前者用于同步
store,后者用于异步 store。Async 的实现逻辑比 Sync
要复杂得多,这是因为它需要考虑数据的延迟加载。这样,如果用户的应用只需要客户端数据,就完全不必用到关于延迟加载的代码,从而减小了最终下载到浏览器的代码量。
[size=0.76em]cacheClass 既可以直接接受 cache
实现的构造函数(如上例),也可以接受 MID,例如:
[size=0.76em]清单 2. 用 MID 设置 cacheClass
参数
var grid = new Gridx({ cacheClass:
"gridx/core/model/cache/Async" ...... })
[size=0.76em]这种写法更适合以 HTML 声明的方式创建 Gridx
的场合,因为它不需要引入额外的变量。
[size=0.76em]目前 Gridx 能够直接支持 dojo(x)/data/* 的老
store 以及 dojo/store/* 的新 store,而不需要任何适配转换。常用的同步 store 有
dojo/data/ItemFileWriteStore 以及 dojo/store/Memory。常用的异步 store 有
dojox/data/JsonRestStore、dojox/data/QueryReadStore 以及
dojo/store/JsonRest。
[size=0.76em]需要特别注意的是,Gridx 要求 store
中的数据行必须具有唯一标识符(ID)。对于老 store 而言,也就是必须要实现 dojo/data/api/Identity
一维数组结构的列声明
var grid = new Gridx({ cacheClass:
Cache store: store, structure: [ {id: 'column1', ......},
{id: 'column2', ......}, {id: 'column3', ......}, ......
] })
[size=0.76em]下面各小节详细介绍列声明中各个属性的含义。
[size=0.76em]id、name、field
[size=0.76em]对于 Gridx
来说,每一列都有一个唯一标识符(ID)。用户最好能指定一些有意义的 ID,从而方便以后的使用。如果用户没有指定,那么 Gridx 会分别赋予"1", "2",
"3", ....... 等字符串类型的自然数作为列的默认 ID。
[size=0.76em]与 DataGrid 类似,name
属性是指表头上显示出来的列名。name 属性可以是任意字符串,甚至可以包含 HTML 标签,从而做出各种定制效果。例如:{id: 'column1',
name: 'Company
Name'}。
[size=0.76em]field 属性也是从 DataGrid 沿袭下来的,指该列在
store 中的对应域。该列中的单元格会从这个 field 域中取得数据。
[size=0.76em]图 1. name 属性作为普通字符串、未指定、以及带 HTML/CSS
的各种情况
[size=0.76em]formatter
函数
[size=0.76em]Gridx 的 formatter 函数与 DataGrid
中的同名函数不同,其目的在于为 Gridx 提供数据,而不是对数据做显示上的修饰。如果某一列没有 field 参数,就可以通过 formatter
函数来提供数据,例如:
[size=0.76em]清单 4. 使用 formatter
函数组合多个域的数据
{id: 'column1', formatter:
function(rawData){ return rawData.field1 + rawData.field2; });
[size=0.76em]这样,这一列就能显示两个数据域的和。
[size=0.76em]图 2. formatter 函数综合多个数据域的内容产生了 Summary
列中的数据
[size=0.76em]formatter 函数所传入的 rawData 参数是以
store 的 field 名称作为 key
的关联数组(对象),包含当前行中的所有数据,形如:
[size=0.76em]清单 5. rawData 格式
rawdata: { field1: data1, field2:
data2, ...... }
[size=0.76em]这种形式要比某些 store(主要是老
store)的数据项(item)更容易使用,也使接口与新 store 保持一致。
[size=0.76em]decorator
函数
[size=0.76em]Gridx
对数据的产生和数据的修饰做了严格的区分。formatter 是用于产生数据,decorator
函数则用于修饰数据。例如:
[size=0.76em]清单 6. 用 decorator 函数为单元格添加
HTML/CSS
{id: 'column1', field: 'field1',
decorator: function(cellData, rowId, rowIndex){ return " href='www.google.com q=" + cellData + "'>" + cellData + "
[size=0.76em]这样就能在单元格中显示出链接。
[size=0.76em]图 3. 使用 decorator
对数据做修饰
[size=0.76em]decorator 函数只能返回字符串,不像 DataGrid 的
formatter 函数还可以返回 widget 实例。关于如何在单元格中显示 widget
的问题将在其他文章中详细介绍。
[size=0.76em]style 和
class
[size=0.76em]通过在 decorator 函数中加入 HTML 标签和
style 属性可以对单元格中的内容做各种修饰,但无法改变单元格本身的样式。要做到这一点,需要 style 或
class:
[size=0.76em]清单 7. 字符串形式的 style 和 class
参数
{id: 'column1', field: 'field1', style:
'text-align: center;', 'class': 'mySpecialColumn' }
[size=0.76em]style 和 class 都会直接加入到
标签的 style 属性和 class 属性。
[size=0.76em]style 和 class
还可以写成一个返回字符串的函数,这样单元格的样式就能随数据而变化:
[size=0.76em]清单 8. 函数形式的 style 和 class
参数
{id: 'column1', field: 'field1', style:
function(cell){ return cell.data() % 2 'color: red;' : 'color:
blue;'}, 'class': function(cell){ return cell.data() %2
'oddClass' : 'evenClass'} }
[size=0.76em]这里 style 和 class 函数所传入的 cell
参数代表了当前所处理的单元格,可以通过各种方便的方法获取有关该单元格的一切信息。
[size=0.76em]图 4. 使用 style
函数为每一个单元格设置独特背景色的例子
[size=0.76em]配置功能模块
[size=0.76em]有了 store、cacheClass 和 structure
后,Gridx 就能运行了。不过这样的 Gridx 除了显示数据之外,几乎没有任何界面功能。Gridx
几乎所有的功能都是由可选模块(module)实现的,需要在创建时声明使用了那些模块。这提供了巨大的灵活性来满足各种不同的需求。
[size=0.76em]声明模块的是 modules
属性:
[size=0.76em]清单
9. 通过 modules 参数配置功能模块
require([ "gridx/Grid",
"gridx/core/model/cache/Sync", "gridx/modules/VirtualVScroller",
"gridx/modules/ColumnResizer", "gridx/modules/Focus",
"gridx/modules/SingleSort", ...... dojo/domReady!" ], function(Gridx,
Cache, VirtualVScroller, ColumnResizer, Focus, SingleSort, ......){ ......
var grid = new Gridx({ cacheClass: Cache store: store,
structure: structure, vScrollerLazy: true,// 模块参数可作为 Gridx 参数传递
modules: [ VirtualVScroller, // 用法 1:直接列举模块构造函数
"gridx/modules/ColumnResizer", // 用法 2:模块 MID {
// 用法 3:带有 moduleClass 的对象 moduleClass: SingleSort,
initialOrder: { colId: 'column1', descending: true } },
{ // 用法 4: moduleClass 也接受 MID moduleClass:
"gridx/modules/Focus"} ] })...... });
[size=0.76em]从上面的例子可见,要使用一个模块先要引入该模块的文件,然后直接列举在
modules 数组中即可。modules 数组中的模块既可以是模块构造函数本身,也可以是模块的 MID,还可以是一个含有 moduleClass
属性的对象。模块本身也可能有参数,这些参数既可以与 moduleClass 一起放在一个对象里(如 initialOrder),也可以直接作为 Gridx
的参数,只不过需要加上所属模块的名称作为前缀(如 vScrollerLazy,这里 vScroller 是模块名称,lazy
是属性名,加上前缀后首字母大写)。模块参数直接作为 Gridx 参数可以使代码更为简洁,因此是推荐的配置方法。
[size=0.76em]上面的例子中加入了 4 个模块:VirtualVScroller
实现了延迟渲染的功能,每次只渲染出需要显示的行,从而可以很快地完成拥有大量数据的 Grid 的创建;ColumnResizer
实现了鼠标拖动改变列宽的功能;SingleSort 是一个单列排序的简单实现;Focus 模块则是对键盘的支持,这是一个被许多其他模块引用的模块,对于 A11y
非常重要。
[size=0.76em]熟悉 DataGrid 的用户会发现这些功能在 DataGrid
中都是默认自带的。虽然这些功能很常用,但用户在不需要它们的时候却难以屏蔽;即使能够屏蔽它们的功能,大量的有关这些功能的代码也依旧存在,而这不失为一种浪费。
[size=0.76em]图 5. 启用了排序、分页、改变列宽、行选择、行首勾选框等多个模块的
Gridx
[size=0.76em]Gridx 的模块化是其最大的特点之一。其实 Gridx
的所有用户界面(包括表头、数据行、纵向滚动条、横向滚动条等)都是模块,只不过这些模块是默认加载的核心模块而已。所谓创建 Gridx
其实就是在一个很小的逻辑内核(称为 Core)的基础上依次创建这些模块。模块之间秉承低耦合的原则,只以 API
和功能相联系而不涉及具体实现,因此几乎所有的模块都是可替换的。同时模块本身是高内聚的,使得维护和调试也更为方便。
[size=0.76em]其他配置参数
[size=0.76em]Gridx 本身还有少数几个参数:如 autoHeight 和
autoWidth,可以由行高和列宽来决定 Gridx 的高度和大小;使用 cache/Async 时的 cacheSize
参数可以配置保存在客户端的最大行数,而 pageSize 可是每次向 store 请求数据时的推荐请求行数。这些参数只有在特殊需求下才有必要使用,具体用法可关注
Gridx 文档。
[size=0.76em]创建 Gridx 时还有一个基本要求就是要指定 Gridx
的大小。Gridx 与 DataGrid 不同,没有默认高度(DataGrid 有 6em 的默认高度),因此必须通过 CSS 为 Gridx
指定高度(除非使用 autoHeight)。同样,也没有默认宽度。
[size=0.76em]目前 Gridx 只支持 Claro 主题,通过
gridx/resources/claro/Gridx.css 可以引入所有与 Gridx 相关的样式。若要支持 RTL,还需要引入
gridx/resources/claro/Gridx_rtl.css。
[size=0.76em]图 6. RTL 状态下采用了 autoWidth 的
Gridx
[size=0.76em]回页首
[size=0.76em]使用 Gridx
API
[size=0.76em]Gridx 本身的 API 很少,主要的 API
来源是其数据模型(grid.model)和各个模块。
[size=0.76em]数据模型 API
[size=0.76em]Gridx 的数据模型(grid.model)是其 MVC 模式的
M 部分,是整个 Grid 的数据层和逻辑层,没有任何用户界面(甚至可以单独使用)。grid.model 的 API 就是为了与 Gridx
的数据进行便捷的交互。主要 API 有:
[size=0.76em]清单 10. grid.model 的常用
API
grid.model.byIndex(rowIndex); grid.model.byId(rowId); grid.model.indexToId(rowIndex); grid.model.idToIndex(rowId); grid.model.size(); grid.model.when(request,
callback)
[size=0.76em]可见除了最后一个 when 函数,都是取数据的 API。这个
when 函数是数据模型中唯一的异步函数,它可以接受一个回调函数作为参数,也会返回一个 Deferred 对象。其语义是:当所请求 request
的数据行都已加载到客户端,且所有改变数据的操作都完成时,调用回调函数
callback。因此典型的用法是:
[size=0.76em]清单 11. grid.model.when
的用法
grid.model.when([1, 3, 5, 7, 9],
function(){ // 获取第 5 行的 ID var rowId = grid.model.indexToId(5); // 获取第
1 行的数据 var rowData = grid.model.byIndex(1).data; // 获取第 9 行的 item var
storeItem = grid.model.byIndex(9).item; })
[size=0.76em]这里的 [1, 3, 5, 7, 9] 是用 index
的方式来请求行。Gridx 也支持通过范围的方式来请求行:
grid.model.when({start: 0, count: 20}, ....)
[size=0.76em]或是用 ID
来请求行:
grid.model.when({id: ['row1', 'row2']}, ....);
[size=0.76em]更多用法请参见文档。
[size=0.76em]grid.model 还有一些 API
可以对数据行的顺序进行改变或者过滤,例如:
[size=0.76em]清单 12. 改变数据模型的 API
grid.model.sort(); grid.model.query(); grid.model.filter(); grid.model.move();
[size=0.76em]这些功能其实是由 model
的扩展(modelExtension)实现的。如果今后出现了其他类型的数据操作需求,就可以以这种扩展的形式进行补充。
[size=0.76em]注意到 Gridx
的数据模型没有提供插入、删除、修改数据的方法,这是因为这些操作都可以直接通过 store 的 API 来完成,Gridx
并不需要提供重复的接口。
[size=0.76em]模块 API
[size=0.76em]模块 API 是 Gridx 的另一大 API 来源。Gridx
的几乎所有模块都可以通过 Gridx 实例直接访问到。例如:
[size=0.76em]清单 13. 访问模块 API
grid.sort.clear(); // 调用 sort 模块的
clear 方法。 grid.columnResizer.setWidth(); // 调用 columnResizer 模块的
setWidth 方法。 grid.select.row.getSelectedIds(); // 行选择模块的 getSelectedIds
方法 grid.select.column.selectById(); // 列选择模块的 selectById 方法 //
甚至核心模块也不例外: grid.header.hidden =
true; grid.body.refresh(); grid.vScroller.scrollToRow();
[size=0.76em]由于每一个模块都有自己的名字空间,因此不容易引发命名冲突。有的模块(如行列选择等)甚至可以创造出更深层次的命名空间,从而使
API 的命名更精简。
[size=0.76em]Gridx 几乎所有主要的功能 API
都由模块提供,这其实简化了各个 API 的命名。例如 selectRow 模块和 selectColumn 模块都可以有 selectById
函数,命名精简的同时在使用的时候仍然具有清晰的语义。每个模块具体的 API 请参考 Gridx 文档。
[
从事外贸工作可以考虑以下考证:
有外语过级证、外销员资格证、单证员资格证、报关员资格证、报检员资格证。目前最缺省的外贸人员有:单证员、报关员、报检员,如果你有这几项中的一项资格证书,上岗是很容易的。
扩展资料:
相关证件说明:
一、国际贸易单证员证书
单证员的工作就是负责国际贸易中运输、海关、商检等环节各种单证的管理和操作。在国际贸易实施过程中,合同、定单、报关、报检、运输、仓储、银行、保险等各个环节,无一不是通过各种单据凭证来维持。
考试内容:该考试包括国际贸易单证操作实务、外经贸英语函电两部分,其中国际贸易单证操作实务又包含国际贸易实务和单证操作实务两部分。
二、国际货运代理员证书
国际货运代理员的工作是接受进出口货物发货人、收货人的委托,为其办理国际货物运输及相关业务。
现有货代企业很多,随着我国对外贸易的发展,货代业的发展前景广阔,货代企业数量将快速增加,对专业人才的需求也将水涨船高。
考试内容:考试包括国际货代业务和国际货代专业英语两部分,其中国际货代业务包含国际货运代理基础知识、国际海上货运代理理论与实务、国际航空货运代理理论与实务、国际多式联运与现代物流理论与实务等内容。
三、外销员从业资格证书
外销员是指在具有进出口经营权的企业从事进出口贸易活动的工作人员,是我国外贸行业的中坚力量。
入世后,我国外贸经营权由审批制改为登记制,准入门槛降低后,具有进出口经营权的企业将大幅增加,对外贸人才的需求也会相应增加。员证书者还有一项优势,在外经贸部招聘我国驻外大使馆经济商务处工作人员时会被优先考虑。
考试内容:包括外贸综合业务、外经贸英语函电和外经贸英语口语三部分。取得原外经贸部颁发的《外销员资格证书》(在有效期内)的人员可免试外经贸外语。
参考资料:
百度百科-国际贸易
版权声明:我们致力于保护作者版权,注重分享,被刊用文章【中国对外贸易中心(集团) 笔试 广州】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;
工作时间:8:00-18:00
客服电话
电子邮件
beimuxi@protonmail.com
扫码二维码
获取最新动态
