Ext动态grid

我们知道,实现extjs的Grid必须先定义一个ColumnModel,指定列名称、列标题、宽度、对齐方式,然后定义一个Record和Store,指定数据源的字段名、类型,最后定义一个Grid,完整过程的代码类似如下: // the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cmCust = new Ext.grid.ColumnModel([{
header: "客户编码",
dataIndex: 'CUSTID',
width: 70
}, {
header: "客户简称",
dataIndex: 'CUSTSHORTNAME',
width: 200
}, {
header: "预收金额",
dataIndex: 'PREPAYMENT',
width: 100,
align: 'right',
renderer: Ext.util.Format.gbMoney
},{
header: "应收金额",
dataIndex: 'PAYMENT',
width: 100,
align: 'right',
renderer: Ext.util.Format.gbMoney
},{
header: "实际欠款",
dataIndex: 'SJQK',
width: 100,
align: 'right',
renderer: Ext.util.Format.gbMoney
},{
header: "信用期限",
dataIndex: 'LICENSEPERIOD',
width: 100,
align: 'right'
},{
header: "信用额度",
dataIndex: 'LICENSEMONEY',
width: 100,
align: 'right',
renderer: Ext.util.Format.gbMoney
}]);

// by default columns are sortable
cmCust.defaultSortable = true;

// this could be inline, but we want to define the order record
// type so we can add records dynamically
var cust = Ext.data.Record.create([
{name: 'CUSTID', type: 'string' },
{name: 'CUSTSHORTNAME', type: 'string'},
{name: 'PREPAYMENT', type: 'float'},
{name: 'PAYMENT', type: 'float'},
{name: 'SJQK', type: 'float'},
{name: 'LICENSEPERIOD', type: 'float'},
{name: 'LICENSEMONEY', type: 'float'}
]);

// create the Data Store
var dsCust = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: '../getCustList.do'}),

// the return will be XML, so lets set up a reader
reader: new Ext.data.DynamicXmlReader({
// records will have a "customer" tag
record: 'table',
totalRecords: 'records'
}, cust)
});

var gridCust = new Ext.grid.DynamicGrid( 'customer-grid', {
ds: dsCust,
cm: cmCust,
selModel: new Ext.grid.RowSelectionModel(),
enableColLock:false,
loadMask: true, });

gridCust.render();

此过程相当繁琐。很多情况下,我们需要一个通用的动态Grid,不必指定字段名、字段类型、列头等信息,而是根据返回记录(通常是json或xml格式)的结构和内容,自动将记录展现在Grid中,这就是Dynamic Grid。

extjs的论坛上有两种方式实现Dynamic Grid,一种是json,另一种是xml。前者请看http://extjs.com/learn/Ext_Extensions。对于xml方式,需要扩展Ext.data.XmlReader和Ext.grid.Grid,具体根据返回的xml的结构,假设返回的xml类似:

<?xml version="1.0" encoding="UTF-8"?>
<response success='true'>
<database>
<record>
<SUPPLIERID><![CDATA[1]]></SUPPLIERID>
<SUPPLIERSHORTNAME><![CDATA[中原公司]]></SUPPLIERSHORTNAME>
<PREPAYMENT><![CDATA[0.00000000]]></PREPAYMENT>
<PAYMENT><![CDATA[0.00000000]]></PAYMENT>
<SJQK><![CDATA[0.00000000]]></SJQK>
</record>
<record>
<SUPPLIERID><![CDATA[2]]></SUPPLIERID>
<SUPPLIERSHORTNAME><![CDATA[广州市五金公司]]></SUPPLIERSHORTNAME>
<PREPAYMENT><![CDATA[0.00000000]]></PREPAYMENT>
<PAYMENT><![CDATA[6855.00000000]]></PAYMENT>
<SJQK><![CDATA[6855.00000000]]></SJQK>
</record>

</database>
</response>
在上面的xml内容中,每个<record>是一个记录,我们必须得到<record>中所有子元素的名称,做为Grid的列标题:

Ext.grid.DynamicColumnModel = function(store) {
var cols = [];
var recordType = store.reader.recordType;
var fields = recordType.prototype.fields;

for (var i = 0; i < fields.keys.length; i++) {
var fieldName = fields.keys[i];
var field = recordType.getField(fieldName);
cols[i] = {
header: field.header,
dataIndex: field.name,
tooltip: field.tooltip,
hidden: field.hidden,
sortable:true,
renderer: eval(field.renderer)
};
}
store.fields = fields;this, cols);
};
Ext.extend(Ext.grid.DynamicColumnModel, Ext.grid.ColumnModel, {});

Ext.data.DynamicXmlReader = function(config) {
Ext.data.DynamicXmlReader.superclass.constructor.call(this, config, []);
};
Ext.extend(Ext.data.DynamicXmlReader, Ext.data.XmlReader, {
getRecordType : function(data) {
recordDefinition = Ext.DomQuery.select( this.meta.record + ':first-child > *', data);
var arr = [];
for (var i = 0; i < recordDefinition.length; i++) {
arr[i] = {
name:recordDefinition[i].tagName,
header:recordDefinition[i].tagName
};
}

this.recordType = Ext.data.Record.create(arr);
return this.recordType;
},

readRecords : function(doc) {
this.xmlData = doc;
var root = doc.documentElement || doc;
this.getRecordType(root);
return Ext.data.DynamicXmlReader.superclass.readRecords.call(this, doc);
}
});

Ext.grid.GridView.prototype.bindColumnModel = function(cm) {
if(this.cm){
this.cm.un("widthchange", this.updateColumns, this);
this.cm.un("headerchange", this.updateHeaders, this);
this.cm.un("hiddenchange", this.handleHiddenChange, this);
this.cm.un("columnmoved", this.handleColumnMove, this);
this.cm.un("columnlockchange", this.handleLockChange, this);
}
if(cm){
this.generateRules(cm);
cm.on("widthchange", this.updateColumns, this);
cm.on("headerchange", this.updateHeaders, this);
cm.on("hiddenchange", this.handleHiddenChange, this);
cm.on("columnmoved", this.handleColumnMove, this);
cm.on("columnlockchange", this.handleLockChange, this);
}
this.cm = cm;
};

Ext.grid.DynamicGrid = function(container, config) {
Ext.grid.DynamicGrid.superclass.constructor.call(this, container, config);
};
Ext.extend(Ext.grid.DynamicGrid, Ext.grid.Grid, {
render : function() {
this.dataSource.addListener('load', this.doReconfiguration, this);
this.colModel = new Ext.grid.DefaultColumnModel([{ header: '', dataIndex: '' }]);
Ext.grid.DynamicGrid.superclass.render.call(this);
},

doReconfiguration : function() {
this.colModel = new Ext.grid.DynamicColumnModel(this.dataSource);
this.view.bindColumnModel(this.colModel);
this.view.refresh(true);
//this.dataSource.removeListener("load", this.doReconfiguration);
}
});

Ext.grid.DynamicColumnModel.superclass.constructor.call(
上面的代码实现了DynamicColumnModel、DynamicXmlReader和DynamicGrid,DynamicXmlReader根据xml文件的结构和内容,自动配置一个ColumnModel和Store,这样最终的Dynamic Grid实现代码如下所示:

var dsCust = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: '../getCustList.do'}),
// the return will be XML, so lets set up a reader
reader: new Ext.data.DynamicXmlReader({
record: 'record',
totalRecords: 'records'
})
});

var gridCust = new Ext.grid.DynamicGrid( 'customer-grid', {
ds: dsCust,
//cm: cmCust,
selModel: new Ext.grid.RowSelectionModel(),
enableColLock:false,
loadMask: true
});
gridCust.render();
相比本文开头的代码简化了很多。当然还有很多地方需要优化,例如实现描述性的列标题(而不是以字段名做为列标题),配置列宽和对齐方式,实现Dynamic EditorGrid等,通常我们还需要一个配置档,将这些原先硬编码的信息在配置档里配置好,然后在返回的json和xml中,除了有结果记录外,还有配置档中的meta信息,以便根据这些信息自动展现Dyanmic Grid。

相比而言,由于json较xml简洁,而且JsonReader本身就支持meta数据,使用JsonReader实现DynamicGrid较XmlReader方式简单,运行效率也高。当然,前提是必须将记录转换成json格式,目前json格式可能不如xml格式使用的多。

需要注意的是,由于Dynamic Grid是在运行时生成ColumnModel,如果你设置了状态管理器,即:Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
那么一旦Dynamic Grid的状态改变,如columnmove/columnresize/sortchange,当重新创建Dynamic Grid时
(例如刷新页面后重新访问),ext会试图先从cookie中读取状态信息,而此时ColumnModel还没有生成,系统就会报错。所以,可考虑关闭状态管理器,或重写Grid的applyState()方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值