Dojo1.6官方教程:连接DataGrid和Store

原作者:Kris Zyp
原文链接:http://dojotoolkit.org/documentation/tutorials/1.6/store_driven_grid/
译者:zhuxw([email protected])

 

鉴于DataGrid对于表格数据的有效呈现,它早已成为许多应用的核心组件之一。在本教程中,我们将着眼于如何为grid连上store(Dojo的客户端数据集——译者注),以进行快捷高效的数据读取和更新。

难度:初等
Dojo版本:1.6

DataGrid和Store

首先,我们将创建一个store。在本例中将创建一个JsonRest store,它将通过JSON REST HTTP成为连接grid和我们的服务器的纽带。创建代码如下:

dojo.require("dojo.store.JsonRest");

myStore = new dojo.store.JsonRest({target:"MyData/"});

以上代码表明这个store将向给定的URL("MyData/")发送请求,以获取或修改数据。

注意:其他类型的store也能使用,例如dojo/store/Memory(原文有误,并不存在dojo/data/Memory。 ——译者注),也能够驱动DataGrid。然而本教程只采用 JsonRest store。

 


现在我们可以创建DataGrid了。在1.6版中DataGrid仍然基于dojo.data API,因此我们将使用接口适配器dojo.data.ObjectStore来连接DataGrid和我们刚刚创建的store。DataGrid采用标准的Dojo小部件的构造方式,因此我们可以用我们的store作为参数来实例化一个DataGrid(同时请确保已经导入了正确的CSS文件(例如使用claro主题的话,可导入dojox/grid/resources/claroGrid.css。——译者注))

dojo.require("dojox.grid.DataGrid");

dojo.require("dojo.data.ObjectStore");

dojo.ready(function(){

    grid = new dojox.grid.DataGrid({

        store: dataStore = dojo.data.ObjectStore({objectStore: myStore}),

        structure: [

            {name:"State Name", field:"name", width: "200px"},

            {name:"Abbreviation", field:"abbreviation", width: "200px"}

        ]

    }, "target-node-id"); // make sure you have a target HTML element with this id

    grid.startup();

});

现在我们已经创建好了grid,当它启动完成后(即调用grid.startup()后——译者注),将调用store的query()方法,从而触发一个请求来获取数据。服务器需要返回一个包含数据的JSON数组作为响应,这样,grid就会将这些数据渲染出来。这个JSON数组形式的响应看上去就像这样:

 

[

    {"id":0,"name":"Alabama","abbreviation":"AL","capital":"Montgomery"},

    {"id":1,"name":"Alaska","abbreviation":"AK","capital":"Juneau"}

]

【示例】

 

好了,现在我们已经有了一个可以正常工作的grid,它能从我们的服务器获取数据。接下来我们来看一下如何增强我们这个组件。

分页

通过响应滚动鼠标滚轮事件来实现即时分页是Dojo DataGrid的强大功能之一。它为浏览大数据集提供了无缝、直观的用户体验——无需点击任何分页控件,只需简单地滚动滚轮即可看到更多数据。这种即时分页是通过向store不断发送一种特殊的请求实现的,这种请求限制了每次返回的数据行数。grid将给store的query()方法传一个请求对象作为其第二个参数,这个对象中有两个属性:start和count。JsonRest store通过HTTP头部属性Range将这两个参数发送到服务器端。这是一个对于可伸缩性非常重要的特性,因为这使得我们能够延迟加载在可视范围之外的行,而不是一下子加载所有数据。向服务器发出的第一个请求如下所示(你可以在浏览器的调试工具中方便地查看这些请求):

GET /MyData/ HTTP/1.1

Range: items=0-19

...

http服务器可以通过Range头来确定需要向客户端发送多少行数据(例如,可以把这个Range头转化为MySQL服务器的LIMIT或OFFSET参数)。对于大规模的数据集,当你将grid向下滚动时,将触发后续的请求。这些后续请求也都具有Range参数,只不过偏移量(起始行号)不同罢了。grid并不直接向服务器发送请求,而是调用store的函数(这些都是自动完成的):

myStore.query("", {start: 0, count: 20}).then(...grid's callback...);

 

排序

DataGrid还支持在点击列头时触发对数据排序的请求。出于性能考虑,grid将实际的排序工作交给了store去做,因为在数据库中进行排序的效率是最高的。当点击一列时,grid将向store发送一个带有sort参数的新请求,这个参数通过query()方法的第二个形参(是一个参数对象)传入。对于JsonRest store来说,这将告诉服务器,返回的数据需要按照某个属性排序(在本例中是“name”属性):

GET /MyData/?sort(+name) HTTP/1.1

Range: items=0-19

...

grid内部通过下面的逻辑向store发出排序请求:

myStore.query("", {start: 0, count: 20, sort:[{attribute:"name"}]}).

        then(...grid's callback...);

grid这种与store的交互方式有一个很重要的特性,那就是这种请求数据的方式使得store的数据视图保持独立。这意味着如果我们在grid外直接向store请求数据,对于grid的显示是没有任何影响的。换句话说,grid对于store的请求只限于其自身,与其他请求是相互独立的。你无法直接对store排序,你只能获取一个排好序的数据视图,这个数据视图就是当你点击列头时grid显示的内容。

 

过滤

除了排序视图外,我们还可以创建过滤视图。这可以通过setQuery()方法做到。DataGrid将把这些参数传给store(和排序与分页一样,过滤数据也最好在数据库层面完成,这样的效率最高)。例如,过滤出所有缩写为“NY”的行,只需要这样写:

grid.setQuery({abbreviation: "NY"});

这句话将触发一个如下请求:

GET /MyData/?abbreviation=NY HTTP/1.1

Range: items=0-19

...

这个请求也将被转化为合适的数据库查询。

在Grid内部,传给setQuery方法的这个请求是作为store.query()方法的第一个参数。如果使用的是JsonRest store,这个请求最终会转化为字符串,接在URL后面以http GET方法的形式发送到服务器端。

 

编辑Grid

DataGrid支持双击后(或单击后)直接编辑单元格,可以提供很好的用户体验。DataGrid通过统一的数据接口将改动写回store。一旦编辑了一个单元格,改变后的数据通过Dojo数据适配器的setValue方法写回,在未保存之前暂时留在适配器中,直到调用了save()方法:

dataStore.save();

调用save()方法后,所有未保存的改动都会通过put()方法保存到store中。


注意:DataGrid经常需要通过ID获取对象。为了避免向服务器发送多余的请求,还可以为store加上一层Cache缓存,从而在本地快速存取缓存的对象:

dojo.require("dojo.store.JsonRest");

dojo.require("dojo.store.Memory");

dojo.require("dojo.store.Cache");

myStore = dojo.store.Cache(

    dojo.store.JsonRest({target:"MyData/"}), 

    dojo.store.Memory());

 

结论

DataGrid是一个功能强大、丰富的表格控件,提供伸缩式的表格数据渲染,还包括排序、过滤、列移动、选择、编辑、键盘导航等等。DataGrid与store的紧密联系使得在Grid中对数据处理进行配置非常容易。

你可能感兴趣的:(datagrid)