标题说明了一切,详情如下。
我有两个相关的模型,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,然后我无法启动批处理以将修改发送到服务器。
我该如何解决这个问题?
答案 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能够检测关系的变化。