1

在我的示例中,网格中记录数据的顺序如下:

  1. 添加所需数量的空记录
  2. 更改所需单元格中的值

这是必要的,以便仅从服务器传输整个表的更改。在某些情况下,可能没有更改,甚至可能会删除某些数据。但主要思想是数据必须分两步改变。问题是数据的重写可能发生在调用渲染的不同时间。在某些情况下,我们会遇到错误。

//error
store.insert(0, new Rec());   
win.show();         
store.insert(0, new Rec());

//no error
store.insert(0, new Rec());     
store.insert(0, new Rec());  
win.show();         

//no error
win.show();         
store.insert(0, new Rec());   
store.insert(0, new Rec()); 

我们无法保证 insert 和 show 函数的执行顺序,因为它们可以从不同的异步请求中调用。

我的问题在下一个; 为什么存储中的更改取决于视图状态,我们如何保护自己免受这种情况的影响?

测试用例

4

2 回答 2

1

看起来在调用 GridView 的 init() (从 Grid 的 调用)之前,GridView 的商店“添加”事件的侦听器不会添加到视图中onRender()。这发生在渲染网格时 (win.show())。您在 #2 (insert-insert-show) 上没有收到错误,因为它从未命中Ext.fly(rows[0]).addClass(this.firstRowCls);GridView 中的processRows().

我稍微更改了代码以在 GridViews init 和 onAdd(商店的添加事件的处理程序)中打印出一些日志记录:

Ext.onReady(function(){

    var cm = new Ext.grid.ColumnModel({
        columns: [{
                dataIndex: 'common',
                editor: new Ext.form.TextField({allowBlank: false})
            }]
    });

    var store = new Ext.data.Store({
        reader: new Ext.data.JsonReader({
            record: 'plant',
            fields: [{name: 'common', type: 'string'}]
        })
    });

    var grid = new Ext.grid.EditorGridPanel({
        store: store,
        cm: cm,
        region: "center",
        view: new Ext.grid.GridView({
            init : function(grid) {
                console.log("\tinit()");
                this.grid = grid;

                this.initTemplates();
                this.initData(grid.store, grid.colModel);
                this.initUI(grid);
            },
            onAdd : function(store, records, index) {
                console.log("\t\tadding: ", records[0].id);
                this.insertRows(store, index, index + (records.length-1));
            }
        })
    });

    var win = new Ext.Window({
        layout: "border",
        items: [grid],
        width : 300,
        height : 300
    });

    var Rec = grid.getStore().recordType;
  /*   
    console.log("show-insert-insert");
    win.show();

    console.log("\t1st insert");
    store.insert(0, new Rec());

    console.log("\t2nd insert");
    store.insert(0, new Rec());     
   */
    console.log("insert-insert-show");
    console.log("\t1st insert");
    store.insert(0, new Rec());

    console.log("\t2nd insert");
    store.insert(0, new Rec());

    console.log("win.show()");
    win.show();
});

以下是三种不同情况的控制台:

show-insert-insert
    init()
    1st insert
        adding: ext-record-1
    2nd insert
        adding: ext-record-2
    win.show()

insert-show-insert
    1st insert
    win.show()
    init()
    2nd insert
        adding: ext-record-2

Ext.fly(rows[0]) is null
[Break On This Error]   
Ext.fly(rows[0]).addClass(this.firstRowCls);
ext-all-debug.js (line 43959

insert-insert-show
    1st insert
    2nd insert
    win.show()
    init()

如您所见,它实际上将两个项目添加到 Grid(和 GridView)的唯一情况是在 show-insert-insert 案例中。到目前为止我发现的最佳解决方案就是做

win.show();
win.hide();

一开始。到目前为止,我还没有找到更好的解决方案。我希望这有帮助。

于 2012-04-19T18:40:56.930 回答
1

或者您可以在显示后刷新 GridView

win.show();
grid.getView().refresh();
于 2012-04-20T10:42:40.973 回答