0

假设我有一张发票和一个发票项目。我想在顶部和下方的网格中显示发票列表我想显示所选发票的相应发票项目。我的 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 时,我希望看到底部网格中显示的项目 11 和 12。然后在选择发票 2 时显示 21 和 22。我不想每次在发票之间切换时都返回服务器。

最后,我希望能够跟踪哪些发生了更改,以便我可以将数据发回以进行持久化。

使用 Ext JS 这一切怎么可能?我还没有看到使用 Ext JS 的工作主细节示例。

4

3 回答 3

1

ExtJS 肯定可以做到这一点,我建议 ExtJS 提供工具来提供帮助。

但是,如果您尝试使用单个存储来包含 JSON 记录,则可能会遇到麻烦。我记得阅读(我搜索了参考,但找不到它)您应该将存储视为单个数据库表,而不是尝试将父/子信息存储在一个存储中。

因此,我谦虚地建议您将发票存储在一个商店中,将发票项目存储在第二个商店中,通过一些参考(发票 ID)将子发票项目链接到父发票,并使用这两个商店来支持两个不同的网格(或任何小部件) - 一个用于发票,另一个用于发票项目。当用户单击发票时,您的侦听器(事件处理程序)将适当地更新发票项目网格/小部件。

这将是我的方法。

于 2010-08-13T12:22:52.503 回答
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();

或者您可能有兴趣查看此树形网格:

http://www.max-bazhenov.com/dev/ux.maximgb.tg/index.php

于 2010-10-31T03:25:03.563 回答
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);

希望这可以帮助。斯图尔特

于 2010-09-18T22:40:20.193 回答