为什么在添加子记录时未定义session.getSaveBatch() - Ext 5.1.1

时间:2016-04-30 23:25:33

标签: session model extjs5

标题说明了一切,详情如下。

我有两个相关的模型,User&作用。

用户的角色定义为:

Ext.define('App.model.security.User', {
    extend: 'App.model.Base',

    entityName: 'User',

    fields: [
        { name: 'id' },
        { name: 'email'},
        { name: 'name'},
        { name: 'enabled', type: 'bool'}
    ],

    manyToMany: 'Role'
});

然后我有一个用户网格和一个表单来编辑用户的数据,包括他的角色。

问题是,当我尝试从用户添加或删除角色时,稍后调用session.getSaveBatch()将返回undefined,然后我无法启动批处理以将修改发送到服务器。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

在阅读了很多内容后,我发现Ext不会至少在5.1.1上保存两个模型之间变化的关系。 我必须通过在左侧模型上放置一个aditional字段(我将其命名为isDirty)并使用默认值false并将其设置为true来强制会话使用getSaveBatch将更新发送到服务器来解决此问题。

稍后我会深入研究代码,以便对BatchVisitor或自定义BatchVisitor类进行覆盖,以便自动保存关联。

请注意,只有在您只想保存两个模型之间的关联时才会出现这种情况,如果您还修改了其中一个涉及的实体,则会在保存批次上发送关联。

答案 1 :(得分:0)

这很有意思,我通过解决这个简单的问题已经学到了很多关于Ext的知识。

我遇到的解决方案是覆盖BatchVisitor类,以便使用从Session类的私有方法visitData引发的事件onCleanRecord的事件处理程序。

因此,对于每条记录,我在矩阵中查找左侧实体,如果有更改,则调用onDirtyRecord的处理程序,该处理程序在BatchVisitor原始类上定义。

代码:

Ext.define('Ext.overrides.data.session.BatchVisitor', {
    override: 'Ext.data.session.BatchVisitor',

    onCleanRecord: function (record) {
        var matrices = record.session.matrices
            bucket = null,
            ops = [],
            recordId = record.id,
            className = record.$className;

        // Before anything I check that the record does not exists in the bucket
        // If it exists then any change on matrices will be considered (so leave)
        try {
            bucket = this.map[record.$className];
            ops.concat(bucket.create || [], bucket.destroy || [], bucket.update || []);

            var found = ops.findIndex(function (element, index, array) {
                if (element.id === recordId) {
                    return true;
                }
            });

            if (found != -1) {
                return;
            }

        }
        catch (e) {
            // Do nothing
        }

        // Now I look for changes on matrices
        for (name in matrices) {
            matrix = matrices[name].left;

            if (className === matrix.role.cls.$className) {
                slices = matrix.slices;

                for (id in slices) {
                    slice = slices[id];
                    members = slice.members;

                    for (id2 in members) {
                        id1 = members[id2][0]; // This is left side id, right side is index 1
                        state = members[id2][2];

                        if (id1 !== recordId) { // Not left side => leave
                            break;
                        }

                        if (state) { // Association changed
                            this.onDirtyRecord(record);
                            // Same case as above now it exists in the bucket (so leave)
                            return;
                        }
                    }
                }
            }
        }
    }
});

它非常适合我的需求,可能它不是其他人的最佳解决方案,但无论如何都可以作为起点。

最后,如果还不清楚,这样做的方法是让方法getSaveBatch能够检测关系的变化。