ExtJS4 网格不会更新远程数据库

Posted

技术标签:

【中文标题】ExtJS4 网格不会更新远程数据库【英文标题】:ExtJS4 grid won't update remote database 【发布时间】:2011-09-03 17:54:48 【问题描述】:

由于某种原因,ExtJS4 网格的这种配置不会更新。当您单击一个单元格,更改一个值时,它会点击创建 URL,而不是更新 URL,正如在代理中定义并在 FF4 中使用 Firebug 观察到的那样。奇怪的是,datachanged 事件在页面启动时加载存储后触发,但在数据实际更改后不会触发。此外,网格将所有行发送到创建 URL。

谁能告诉我我做错了什么?

Ext.onReady(function() 

    Ext.BLANK_IMAGE_URL = '/images/extjs4/s.gif';
    Ext.tip.QuickTipManager.init();
    //Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));

    Ext.define('VendorError', 
        extend: 'Ext.data.Model',
        fields: [
            name: 'UnexpSrvID', type: 'int',
            name: 'VendorID', type: 'int',
            name: 'VendorName', type: 'string',
            name: 'VndActID', type: 'int',
            name: 'VndActNb', type: 'string',
            name: 'InvoiceID', type: 'int',
            name: 'VInvNb', type: 'string',
            name: 'VInvRcptDt', type: 'date', dateFormat: 'Y-m-d' ,
            name: 'InvDate', type: 'date', dateFormat: 'Y-m-d' ,
            name: 'CodeSpecifier', type: 'string',
            name: 'Recurrence', type: 'string',
            name: 'ClientID', type: 'int',
            name: 'ClientName', type: 'string',
            name: 'LocID', type: 'int',
            name: 'LocName', type: 'string',
            name: 'RecentLocStatus', type: 'string',
            name: 'RecentLocStatusDate', type: 'date', dateFormat: 'Y-m-d' ,
            name: 'UnexpCost', type: 'float',
            name: 'ConfirmedAmt', type: 'float',
            name: 'StaffID', type: 'int',
            name: 'NetworkID', type: 'string',
            name: 'UnexpStatCode', type: 'string'
        ],
        proxy: 
            type: 'ajax',
            simpleSortMode: true,
            api: 
                read: '/internal/viewVERext_json.asp',
                create: '/internal/viewVERext_create.asp',
                update: '/internal/viewVERext_update.asp',
                destroy: '/internal/viewVERext_destroy.asp'
            ,
            reader: 
                type: 'json',
                totalProperty: 'total',
                successProperty: 'success',
                messageProperty: 'message',
                root: 'data'
            ,
            writer: 
                type: 'json',
                writeAllFields: false,
                allowSingle: false,
                root: 'data'
            ,
            listeners: 
                exception: function(proxy, response, operation)
                    Ext.MessageBox.show(
                        title: 'REMOTE EXCEPTION',
                        msg: operation.getError(),
                        icon: Ext.MessageBox.ERROR,
                        buttons: Ext.Msg.OK
                    );
                
            
        
    );

    var store = Ext.create('Ext.data.Store', 
        model: 'VendorError',
        autoLoad: true,
        autoSync: true,
        pageSize: 20,
        remoteSort: true,
        listeners: 
        //  write: function(proxy, operation)
        //      if (operation.action == 'destroy') 
        //          main.child('#form').setActiveRecord(null);
        //      
        //      Ext.example.msg(operation.action, operation.resultSet.message);
        //  
            datachanged: function() 
                var report = "";
                store.each( 
                    function(rec)  
                        report = report + rec.dirty + '/';
                     
                )
                alert(report);
            
        
    );

    // create the Grid
    var grid = Ext.create('Ext.grid.Panel', 
        store: store,
        //stateful: true,
        //stateId: 'stateGrid',
        columns: [
               text     : 'Vendor',
                dataIndex: 'VendorName',
                flex     : 1
            ,
               text     : 'Account',
                dataIndex: 'VndActNb'
            ,
               text     : 'Invoice',
                dataIndex: 'VInvNb'
            ,
               text     : 'Invoiced',
                dataIndex: 'InvDate', 
                xtype    : 'datecolumn',
                align    : 'center'
            ,
               text     : 'Receipted',
                dataIndex: 'VInvRcptDt', 
                xtype    : 'datecolumn',
                align    : 'center'
            ,
               text     : 'Description',
                dataIndex: 'CodeSpecifier'
            ,
               text     : 'Client',
                dataIndex: 'ClientName'
            ,
               text     : 'Location',
                dataIndex: 'LocName'
            ,
               text     : 'LStatus',
                dataIndex: 'RecentLocStatus',
                align    : 'center'
            ,
               text     : 'Credit',
                dataIndex: 'UnexpCost',
                tdCls    : 'colyellow',
                renderer : Ext.util.Format.usMoney,
                align    : 'right',
                field    :  xtype:'textfield', allowBlank:false 
            ,
               text     : 'Confirmed',
                dataIndex: 'ConfirmedAmt',
                tdCls    : 'colyellow',
                renderer : Ext.util.Format.usMoney,
                align    : 'right',
                field    :  xtype:'textfield', allowBlank:false 
            ,
               text     : 'Recurrence',
                dataIndex: 'Recurrence',
                tdCls    : 'colyellow',
                align    : 'center',
                field    : 
                    xtype    : 'combobox',
                    typeAhead: true,
                    triggerAction: 'all',
                    selectOnTab: true,
                    store: [
                        ['once','once'],['1st','1st'],['2nd+','2nd+']
                    ],
                    lazyRender: true
                
            ,
               text     : 'CStatus',
                dataIndex: 'UnexpStatCode',
                tdCls    : 'colyellow',
                align    : 'center',
                field    : 
                    xtype    : 'combobox',
                    typeAhead: true,
                    triggerAction: 'all',
                    selectOnTab: true,
                    store: [
                        <%=cstat_grid%>
                    ],
                    lazyRender: true
                
            ,
               text     : 'Owner',
                dataIndex: 'NetworkID',
                tdCls    : 'colyellow',
                field    : 
                    xtype    : 'combobox',
                    typeAhead: true,
                    triggerAction: 'all',
                    selectOnTab: true,
                    store: [
                        <%=staff_grid%>
                    ],
                    lazyRender: true
                
            
        ],
        layout: 'fit',
        height: 500,
        renderTo: 'theGrid',
        selType: 'cellmodel',
        plugins: [
            Ext.create('Ext.grid.plugin.CellEditing', 
                clicksToEdit: 1
            )
        ],
        dockedItems: [
               xtype: 'pagingtoolbar',
                store: store,
                dock: 'bottom',
                displayInfo: true
            ,
               xtype: 'toolbar',
                dock: 'top',
                items: [
                     xtype:'button', 
                      text: 'IsDirty()', 
                      handler: function()  
                        var report = "";
                        store.each( 
                            function(rec)  
                                report = report + rec.dirty + '/';
                             
                        )
                        alert(report);
                        
                    
                ]
            
        ],
        viewConfig: 
            stripeRows: true
        
    );

    Ext.EventManager.onWindowResize(grid.doLayout, grid);
);

【问题讨论】:

【参考方案1】:

原来的问题是添加到网格中的记录被唯一 id 字段的值检测为“不是新的”。 Sencha 论坛上的 poster 向我指出了这一点。

默认情况下,模型中的此字段的名称应为“id”。因此,您必须提供一个具有“id”字段的模型,而我上面的模型没有,或者您必须使用Ext.data.Model 的 idProperty 属性覆盖默认列。我只是将UnexpSrvId 列重命名为id。而且,你瞧,我们将更新发送到 update() 而不是 create()。

这在 API 文档中并不明显,因为不幸的是,很多东西都在这个强大的框架中。

【讨论】:

【参考方案2】:

因为您的网格使用CellEdit 混合,您可以向grid 添加一个侦听器,它将在编辑后将更改提交到您的记录。因此,在您的网格中,添加如下定义的 listeners 配置选项...

listeners: 
    edit : function(e) 
        e.record.commit();
    

编辑:我认为您在代理上使用了错误的语法...您只能定义读取器和写入器(从外观上看)...

Ed Spencer's article on Proxies

ExtJS 4 API Entry on Proxies

【讨论】:

"因为你的网格使用 CellEdit mixin" 那么,使用插件会更新单个单元格,触发代理上的创建(而不是更新)并将所有行发送给它?这似乎是非常错误的。此外,问题不在于没有任何东西进入服务器,而是所有 20 行都被发送到创建 URL! 我现在只是将 ExtJS 4 下载到我的机器上,我会试一试,因为我不相信这是答案......如果不是,我很抱歉 没问题!非常感谢您的时间。 实际上,它是一个 Ajax 代理,它具有允许更多特异性的 'api' 属性。 docs.sencha.com/ext-js/4-0/#/api/Ext.data.proxy.Ajax 嗯,在文档的搜索中没有看到这个。我对 ExtJS 4 还有些陌生……所以我很抱歉

以上是关于ExtJS4 网格不会更新远程数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何在 extjs4.1 中动态更新网格的摘要类型

ExtJs 4.1 网格远程排序客户端事件

store.load 后的 Extjs 网格选择有不正确的数据

如果网格为空,Extjs 4 禁用排序

网格中缺少滚动条,缓冲网格中缺少数据,布局不会调整大小

如何在 extjs4 的网格中显示关联的 json 数据?