为什么在添加 child 记录时未定义 session.getSaveBatch() - Ext 5.1.1
Why session.getSaveBatch() is undefined when child record was added - Ext 5.1.1
标题说明了一切,详情如下。
我有两个相关模型,用户和角色。
用户的角色定义为:
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() returns undefined 尝试向用户添加或删除角色时,我无法启动批处理以将修改发送到服务器。
我该如何解决这个问题?
嗯,看了很多之后发现Ext至少在5.1.1上不会保存两个模型之间变化的关系。
我不得不通过在左侧模型上放置一个默认值为 false 的附加字段(我将其命名为 isDirty)来解决此问题,并将其设置为 true 以强制会话使用 getSaveBatch 将更新发送到服务器。
稍后我将深入研究代码,以编写对 BatchVisitor 或自定义 BatchVisitor class 的覆盖,以允许自动保存关联。
请注意,只有当您只想保存两个模型之间的关联时才会发生这种情况,并且如果您还修改了其中一个相关实体,那么关联将在保存批处理时发送。
这很有趣,通过解决这个简单的问题,我学到了很多关于 Ext 的知识。
我遇到的解决方案是重写 BatchVisitor class 以对从 Session class 的私有方法 visitData 引发的事件 onCleanRecord 使用事件处理程序 class。
因此,对于每条记录,我在矩阵中查找左侧实体,如果有变化,则调用 onDirtyRecord 的处理程序,该处理程序在 BatchVisitor 原始 class.
上定义
代码:
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 能够检测关系的变化。
标题说明了一切,详情如下。
我有两个相关模型,用户和角色。
用户的角色定义为:
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() returns undefined 尝试向用户添加或删除角色时,我无法启动批处理以将修改发送到服务器。
我该如何解决这个问题?
嗯,看了很多之后发现Ext至少在5.1.1上不会保存两个模型之间变化的关系。 我不得不通过在左侧模型上放置一个默认值为 false 的附加字段(我将其命名为 isDirty)来解决此问题,并将其设置为 true 以强制会话使用 getSaveBatch 将更新发送到服务器。
稍后我将深入研究代码,以编写对 BatchVisitor 或自定义 BatchVisitor class 的覆盖,以允许自动保存关联。
请注意,只有当您只想保存两个模型之间的关联时才会发生这种情况,并且如果您还修改了其中一个相关实体,那么关联将在保存批处理时发送。
这很有趣,通过解决这个简单的问题,我学到了很多关于 Ext 的知识。
我遇到的解决方案是重写 BatchVisitor class 以对从 Session class 的私有方法 visitData 引发的事件 onCleanRecord 使用事件处理程序 class。
因此,对于每条记录,我在矩阵中查找左侧实体,如果有变化,则调用 onDirtyRecord 的处理程序,该处理程序在 BatchVisitor 原始 class.
上定义代码:
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 能够检测关系的变化。