Extjs6 更新Model中的Id值后,本地删除不了该model记录

在stroe中插入一条数据

onAddFileUploadCfg: function(btn) {
        var grid = btn.up('grid'),
            viewModel = this.getView().getViewModel(),
            plugin = grid.findPlugin('rowediting'),
            store = grid.getStore(),
            count = store.getCount(),
            record = new smartgen.model.FileModel({
                parentId: viewModel.get('fileUploadParentId'),
                cfgName: '',
                cfgCode: '',
                fileHost: '',
                port: '',
                fileRoot: '',
                appId: '',
                companyId: '',
                remark: '',
                category: 'PC',
                singleDate: false,
                leaf: true
            });
        store.insert(count, record);
        plugin.cancelEdit();
        plugin.startEdit(record, 0);
    }

以上添加好数据后,将数据保存到服务器后台,后台会返回id到前端,这时候前端需要更新model中的id

saveFile: function(editor, context, eOpts){
        var view = this.getView(),
            params = context.record.data;
        for(var key in params){
            if(!params[key]){
                delete params[key];
            }
        }
        Ext.Ajax.request({
            method: 'POST',
            url: '../file/save',
            params: params,
            success: function(response, opts) {
                var result = Ext.decode(response.responseText);
                view.toast(result.message);
                context.record.set('id', result.records.id);
                context.record.commit();
            },
            failure: function(response, opts) {

            }
        });
    },

再执行 Store.remove(record);总是删除不了


    onDeleteFileCfg: function(btn){
        var view = this.getView();
        Ext.Msg.confirm('系统提示', '确定删除所选择的文件上传配置数据吗!', function (but) {
            if (but == 'yes') {
                var grid = btn.up('grid'),
                    records = grid.getSelectionModel().getSelection(),
                    params = {
                        ids: []
                    };
                Ext.each(records, function (record) {
                    params.ids.push(record.get('id'));
                });
                Ext.Ajax.request({
                    url: '../file/delete',
                    method: 'post',
                    params: params,
                    success: function (response, action) {
                        var result = Ext.decode(response.responseText);
                        view.toast(result.message);
                        grid.getStore().remove(records);
                    }
                });
            }
        });
    },

chrome debugger查看了一下,发现record中的Data数据是更新了,但是映射的getData()中的Map的key值没有更新

  修改id值后的model 

再来看看store.getData().map的值,发现新的id并没有给更新 

再查看store.remove()的源码发现

/**
     * Removes the specified record(s) from the Store, firing the {@link #event-remove}
     * event for the removed records.
     *
     * After all records have been removed a single `datachanged` is fired.
     *
     * @param {Ext.data.Model/Ext.data.Model[]/Number/Number[]} records Model instance or
     * array of instances to remove or an array of indices from which to remove records.
     * @param isMove (private)
     * @param silent (private)
     */
    remove: function(records, isMove, silent) {
        var me = this,
            data = me.getDataSource(),
            len, i, toRemove, record;

        if (records) {
            if (records.isModel) {
                if (data.indexOf(records) > -1) {
                    toRemove = [records];
                    len = 1;
                } else {
                    len = 0;
                }
            } else {
                toRemove = [];
                for (i = 0, len = records.length; i < len; ++i) {
                    record = records[i];

                    if (record && record.isEntity) {
                        if (!data.contains(record)) {
                            continue;
                        }
                    } else if (!(record = data.getAt(record))) { // an index
                        continue;
                    }

                    toRemove.push(record);
                }

                len = toRemove.length;
            }
        }

        if (!len) {
            return [];
        }

        me.removeIsMove = isMove === true;
        me.removeIsSilent = silent;
        data.remove(toRemove);
        me.removeIsSilent = false;
        return toRemove;
    }

 

if (!data.contains(record)) {
    continue;
}

这个判断就过滤掉了record将被删除,再看看contains这个方法

/**
     * Returns true if the collection contains the passed Object as an item.
     * @param {Object} item The item to look for in the collection.
     * @return {Boolean} `true` if the collection contains the item.
     * @since 5.0.0
     */
    contains: function (item) {
        var ret = false,
            key;

        if (item != null) {
            key = this.getKey(item);
            ret = this.map[key] === item;
        }

        return ret;
    }

就是上图中从map中去查找是否存在对应的record;

既然知道问所在,那就好解决了,可以绕过model默认的注解属性名称id,将这个主键的属性名设置其他的名称,避免冲突

通过查找Ext.data.Model的API发现还真可以解决,用idProperty来设置主键的属性名称

Ext.define('extjstest.model.FileModel', {
    extend: 'extjstest.model.BaseModel',
    /**
     * 设置model中默认主键的字段名称,默认就是id,由于后台的主键也是id
     * 在新增成功后,后台返回的id需要更新到Model中,但是
     * record.set('id', 'newId');
     * record.commit();
     * store.remove(record);
     * 这样是删除不掉该条记录的,原因是record中的Data数据是更新了,但是映射的getData()中的Map的key值没有更新
     * 还是原来model自动生成的主键值,由于找不到新的Key值,所以就删除不了
     * 所有这里更改model中默认的主键为fid,避免一些操作异常。
      */
    idProperty: 'fid',
    fields: [
        /**
         * 服务器地址
         */
        {name: 'fileHost',  type: 'string'},
        /**
         * 端口
         */
        {name: 'port',  type: 'string'},
        /**
         * 文件更目录
         */
        {name: 'fileRoot',  type: 'string'}
    ]
});

至此在执行

record.set('id', result.records.id);

record.commit();

store.remove(record);

就可以成功删除了。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页