假设我有发票和发票项目。我想在顶部和下方的网格中显示发票清单,我想在选定的发票中显示相应的发票项目。我有SQL和JSON部分很好。我查询发票,查询发票所有发票的发票项目(只有2个查询)。然后我将这些项目与他们的发票进行匹配。最后我将其转换为JSON。它看起来像这样。
{
"success": true,
"results": 2,
"rows": [
{
"data": {"id": 1, "invoiceDate": "2010-01-01", "total": "101.00" },
"invoiceItems": [
{"id": 11, "invoiceID": 1, "item": "baseball", "subtotal": "50.00" },
{"id": 12, "invoiceID": 1, "item": "bat", "subtotal": "51.00" }
]
},
{
"data": {"id": 2, "invoiceDate": "2010-02-02", "total": "102.00" },
"invoiceItems": [
{"id": 21, "invoiceID": 2, "item": "hat", "subtotal": "52.00" },
{"id": 22, "invoiceID": 2, "item": "baseball", "subtotal": "50.00" }
]
}
]
}
因此,当我在顶部网格中选择发票1时,我希望看到在botton网格中显示的项目11和12。然后在选择发票2时显示21和22。每次我在发票之间切换时,我都不必返回服务器。
最后,我希望能够跟踪哪些内容发生了变化,以便我可以将数据发送回来保存。
使用Ext JS如何才能实现这一切?我还没有看到使用Ext JS的工作主要细节示例。
答案 0 :(得分:1)
ExtJS当然可以做到这一点,我建议ExtJS提供帮助的工具。
但是,如果您尝试使用单个商店来包含JSON记录,则可能会遇到麻烦。我记得阅读(我搜索了一个参考,但无法找到它)你应该把商店看作一个数据库表,而不是试图在一个商店中存储父/子信息。
因此,我谦虚地建议您将发票存储在一个商店中,将发票项目存储在第二个商店中,通过一些参考(发票ID)将子发票项目链接到父发票,并使用这两个商店来支持两个不同的商店网格(或任何小部件) - 一个用于发票,另一个用于发票项目。当用户单击发票时,您的侦听器(事件处理程序)将相应地更新发票项目网格/窗口小部件。
这将是我的方法。
答案 1 :(得分:1)
在这种情况下,您需要两个读者代码如下:
var reader2 = new Ext.data.JsonReader({
root: 'invoiceItems',
fields: [{name: 'id', type:'int'},
{name: 'invoiceID', type:'int'},
{name: 'item', type:'string'},
{name: 'subtotal': type:'float'}]
});
var reader = new Ext.data.JsonReader({
idProperty: 'id',
totalProperty: 'results',
successProperty: "success",
root: 'rows',
fields: [
{name: 'id', type:'int'},
{name: 'invoiceDate', type:'date'},
{name: 'total', type:'float'},
{name: 'invoiceItems', convert: function(v, n){ return reader2.readRecords(n).records;} }//v: value, n: data;
]
});
var conn = new Ext.data.Connection({
timeout : 120000,
url: 'address-path-to-get-json-data',
method : 'POST'
});
var dproxy = new Ext.data.HttpProxy(conn);
var gstore = new Ext.data.Store({
proxy: dproxy,
reader: reader,
sortInfo:{field: 'id', direction: "DESC"}
});
以下是渲染网格所需的代码
var numrender = function(value, cell, rec, rowIndex, colIndex, store){
if(value*1>0){
return Ext.util.Format.number( value, '0,000.00');
}else return '-';
}
var invoicedetail = function(value, cell, rec, rowIndex, colIndex, store) {
var html = '<div class="itemdetail">{0} - {1} - {2} - {3}</div>';
var re = '';
Ext.each(value,function(item,index){
re += String.format(html,item.get('id'),item.get('invoiceID'),item.get('item'),item.get('subtotal'));
});
return re;
}
var cm = [
new Ext.grid.RowNumberer({header:"No.", width: 30}),
{header: "ID", align: 'left',sortable:true, width: 40, dataIndex: 'id'},
{header: "Invoice Date", align: 'left',sortable:true, width: 40, dataIndex: 'invoiceDate'},
{header: "Total", align: 'right', width: 30, dataIndex: 'total', renderer: numrender},
{header: "Invoice Items", align: 'left',sortable:false, id:'col_detail', width: 100, dataIndex: 'invoiceItems', renderer: invoicedetail}
];
var grid = new Ext.grid.GridPanel({
id:'invoices',
store: gstore,
columns: cm,
enableHdMenu: false,
loadMask: {msg:'Loading Invoices ...'},
enableColumnResize:false,
stripeRows: true,
viewConfig: { autoFill: true },
columnLines : true,
autoExpandColumn: 'col_detail',
renderTo:'grid-wrapper'
});
gstore.load();
或者你可能有兴趣看看这个treegrid:
答案 2 :(得分:0)
这当然是可能的,但是你并没有真正映射子对象,而只是期望它们在那里......
考虑这个测试用例(将其粘贴到FireBug中,你应该看到结果......)
var store = new Ext.data.JsonStore({
data: {
success: true, result: [
{
test: {prop1: 1, prop2: 2}
}]
},
root: 'result',
fields: ['test']
});
console.log(store.getRange()[0].data.test.prop1); // prints "1"
在您的实例中,您可以在行选择事件中执行类似的操作...
//assume "this" = your panel containing your Grid (at position 0) and another Grid (at position 1)
var selectedRowRecord = this.get(0).getSelectionModel().getSelected();
var invoiceItemsStore = this.get(1).getStore();
invoiceItemsStore.removeAll();
invoiceItemsStore.loadData(selectedRowRecord.data.invoiceItems);
希望这会有所帮助。 斯图尔特