You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ext JS模态窗口添加数据后自动刷新Grid的问题求助

Ext JS Grid插入数据后自动刷新问题

我是Ext JS新手,现有一个Grid组件,尝试通过模态窗口插入新数据,希望数据存入Store后Grid能自动刷新。以下是相关代码:

Customer Model

Ext.define('Customer', {
    extend: 'model.Base',
    alias :  'Customer',

    fields: [
        { name : 'id', type :'int', persist : false },
        { name : 'first_name', type : 'string'},
        { name : 'last_name', type : 'string'},
        { name : 'birthday', type : 'date',  dateWriteFormat:'Y-m-d'},
        { name : 'phone_no', type : 'string'},
        { name : 'email', type : 'string'},
        { name : 'username', type : 'string'},
        { name : 'password', type : 'string'},
    ],
});

Customer Store

Ext.define('Customer', {
    extend: 'Ext.data.Store',
    alias: 'store.customer',
    model: 'model.Customer',
    pageSize : 25,
    id : 'customerId',
    autoSave : false,
    autoSync : false,

    require :[
        'model.Customer'
    ],

    proxy:{
        type: 'rest',
        enablePaging : true,
        batchActions : true,
        api :{
            read: '/api/Customer/pagination/',
            create: '/api/Customer/',
            update: '/api/Customer/',
            destroy: '/api/Customer/',
        },

        reader: {
            type: 'json',
            rootProperty: 'Customer',
            totalProperty : 'TotalCount'
        },
        writer: {
            type: 'json',
            dateFormat: 'Y-m-d',
            // writeAllFields: false,
        },

        listeners: {
            exception: function(proxy, response, operation, eOpts) {
                if(response.responseJson.Message){
                    this.showToast(response.responseJson.Message);
                }
            },
        },

        showToast: function(s) {     
            Ext.toast({
                html: s,
                closable: false,
                align: 't',
                slideDUration: 400,
                maxWidth: 400
            });
        },
    },
});

Customer ViewModel

Ext.define('CustomerViewModel', {
    extend: 'Ext.app.ViewModel',
    alias: 'viewmodel.customer',
    deep : true,

    data: {
        userData : null,
    },

    stores :{
        customerStore :{
            type : 'customer'
        },
    },
});

Customer Controller

Ext.define('CustomerController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.customer',

    showAddForm : function(){
        var form = Ext.ComponentQuery.query('AddCustomer')[0];
        if (!form) {
            form = Ext.create('VidlyApp.view.customer.AddCustomer');
        }
        if (form.isHidden()) {
            form.show();
        }
    },

    onAddCustomer : function(){
        var me = this;
        var viewmodel  = me.getViewModel();
        var store  = viewmodel.get('customerStore');
        store.add(viewmodel.data.userData);
        // store.insert( 0,viewmodel.data.userData);
        store.sync({
            success: function(response, request) {
                me.showToast("Account Successfully Created!");
                me.getView().destroy();
            },
            failure :function(response){
                store.rejectChanges();
                me.showToast("Operation Failed! Something went wrong!");
            }
        });
    },

    showToast: function(s) {
        Ext.toast({
            html: s,
            closable: false,
            align: 't',
            slideDUration: 400,
            maxWidth: 400
        });
    }

});

Customer List - View

Ext.define('CustomerList', {
    extend: 'Ext.grid.Panel',
    xtype: 'customerlist',
    controller: 'customer',
    title: 'Customer',
    width : '99%',
    height: 700,
    border : 1,

    requires: [
        'VidlyApp.store.Customer',
        'Ext.grid.column.Action',
        'Ext.toolbar.Paging',
    ],

    viewModel: {
        type : 'customer',
    },

    bind : {
        store: '{customerStore}',
    },


    columns: [
        { xtype: 'rownumberer' },
        { text: 'id',  dataIndex: 'id' },
        { text: 'First Name',  dataIndex: 'first_name', flex : 1 },
        { text: 'Last Name',  dataIndex: 'last_name',  flex : 1},
        { text: 'Birthday',  dataIndex: 'birthday', formatter: 'date("m/d/Y")' },
        { text: 'Phone No.', dataIndex: 'phone_no',  flex : 1},
        { text: 'Email', dataIndex: 'email',  flex : 1},
        { text: 'Username', dataIndex: 'username',  flex : 1},
        { text: 'Password', dataIndex: 'password' },
        {
            text: 'Actions',
            xtype:'actioncolumn',
            width:100,
            items: [{
                icon: 'EditIcon.png',
                tooltip: 'Edit',
                handler : 'showEditForm'
            },{
                icon: 'deleteIcon,png',
                tooltip: 'Delete',
                handler : 'onDeleteCustomer'
            }]
        }
    ],
});

AddCustomer (Modal Window) - View

Ext.define('AddCustomer', {
    extend: 'Ext.window.Window',
    alias: 'widget.AddCustomer' ,
    controller : 'customer',
    title: 'Add Customer',
    autoDestroy: false,
    viewModel : 'customer',

    items: [
        {
            xtype : 'form',
            reference: 'form',
            layout : 'vbox',
            bodyPadding:20, 
            width:400,
            height:500,
            default :{
                width:400,
                height:500,
            },
            defaultType: 'textfield',
            items: [{
                fieldLabel: 'First Name',
                bind: '{userData.first_name}',
                allowBlank:false,
            }, {
                fieldLabel: 'Last Name',
                bind: '{userData.last_name}',
                allowBlank:false,
            }, {
                xtype: 'datefield',
                format: 'Y-m-d',
                fieldLabel: 'Birth Date',
                bind: '{userData.birthday}',
                maxValue: new Date(),
                allowBlank:false,
            }, {
                xtype: 'textfield',
                fieldLabel: 'Phone No',
                bind: '{userData.phone_no}',
                allowBlank:false,
            }, {
                fieldLabel: 'Email',
                bind: '{userData.email}',
                vtype: 'email',
                allowBlank:false,
            }, {
                fieldLabel: 'Username',
                bind: '{userData.username}',
                allowBlank:false,
            }, {
                fieldLabel: 'Password',
                bind: '{userData.password}',
                inputType : 'password',
                allowBlank:false,
            }, {
                fieldLabel: 'Confirm Password',
                bind: '{userData.confirm_password}',
                inputType : 'password',
                allowBlank:false,
            },
        ],

            buttons: [{
                text: 'Add',
                formBind: true,
                listeners: {
                    click : 'onAddCustomer'
                }
            }],
        }
    ],

    listeners:{
        close: 'close',
    },
});

解决方案

1. 修复Store与Model命名冲突

Store类名不能和Model重复,将Store的类名改为CustomerStore,确保命名唯一:

Ext.define('CustomerStore', {
    extend: 'Ext.data.Store',
    alias: 'store.customer',
    model: 'model.Customer',
    // ... 其他代码保持不变
});

2. 初始化ViewModel的userData为Customer实例

ViewModel中userData初始为null会导致绑定异常,改为初始化新的Model实例:

Ext.define('CustomerViewModel', {
    extend: 'Ext.app.ViewModel',
    alias: 'viewmodel.customer',
    deep : true,

    data: {
        userData: Ext.create('model.Customer')
    },

    stores :{
        customerStore :{
            type : 'customer'
        },
    },
});

3. 同步成功后刷新Store(适配分页场景)

由于Store启用了分页,新添加的数据可能在第一页,在sync的成功回调中调用loadPage(1)强制刷新第一页数据:

onAddCustomer : function(){
    var me = this;
    var viewmodel  = me.getViewModel();
    var store  = viewmodel.get('customerStore');
    store.add(viewmodel.get('userData')); // 改用get方法获取绑定数据
    store.sync({
        success: function(response, request) {
            me.showToast("Account Successfully Created!");
            me.getView().destroy();
            // 刷新第一页数据,确保Grid显示新添加的记录
            store.loadPage(1);
        },
        failure :function(response){
            store.rejectChanges();
            me.showToast("Operation Failed! Something went wrong!");
        }
    });
},

4. 修正其他小问题

  • Store中的require改为requires(拼写错误);
  • Customer List视图中ActionColumn的删除图标路径修正为deleteIcon.png(逗号改点);
  • AddCustomer窗口的default配置改为defaults(拼写错误),避免布局异常。

注意事项

  • 确保后端API在创建数据后返回正确的响应,包含新记录的完整信息,这样Store能自动更新本地缓存;
  • 如果不需要分页,可以将Store的pageSize移除,改为autoLoad: true,同步后直接调用store.reload()即可。

内容的提问来源于stack exchange,提问作者Owl Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:42:01