以下是我所拥有的:
单击其中一个框时,下面的列表将在服务器端进行过滤。
如果我选择网格中的行然后提交过滤器,我会收到以下错误:
“getById调用了本地缓存中不存在的ID”
即使过滤器确实包含我选择的记录,也会引发此问题。
这是模块:
Ext.define('NG.model.auxClasses.notifications.WhatsNew', {
extend: 'Ext.data.Model',
idProperty: 'iD',
autoLoad: true,
fields: [
{ name: 'iD', type: 'int' },
{ name: 'isActive', type: 'boolean' },
{ name: 'documentIdentifier', type: 'string' },
{ name: 'sourceSiteName', type: 'string' },
{ name: 'targetSiteName', type: 'string' },
{ name: 'createDate', type: 'date', dateFormat: 'c' },
{ name: 'businessArchiveEvent', type: 'string' },
{ name: 'businessArchive', type: 'string' },
{ name: 'previousWhatsNewEvents' },
{ name: 'isPin', type: 'boolean' },
{ name: 'IsDocumentReadByMe', type: 'boolean' },
{ name: 'isDocumentReadByOthers', type: 'boolean' },
{ name: 'documentYear', type: 'int' },
{ name: 'businessDirection', type:'int'}
],
// self association model
associations: [{
type: 'hasMany',
model: 'auxClasses.notifications.WhatsNew',
name: 'previousWhatsNewEvents',
primaryKey: 'id',
associationKey: 'previousWhatsNewEvents'
}],
proxy: {
type: 'rest',
url: 'api/WhatsNew/'
}
});
这是商店:
Ext.define('NG.store.WhatsNews', {
extend: 'NG.store.AbstractStore',
model: 'NG.model.auxClasses.notifications.WhatsNew',
alias: 'store.whatsnewstore',
autoLoad:true,
buffered: true,
pageSize: 50
});
更新
我跟着兔子走到了洞口,找到了一个我不确定会起作用的解决方法:
这是我失败的地方:
refresh: function() {
...
// Don't need to do this on the first refresh
if (me.hasFirstRefresh) {
// Some subclasses do not need to do this. TableView does not need to do this.
if (me.refreshSelmodelOnRefresh !== false) {
me.selModel.refresh();
} else {
// However, even if that is not needed, pruning if pruneRemoved is true (the default) still needs doing.
me.selModel.pruneIf(); <<< HERE WE FAIL. THIS METHODS CALLS THE GET BY ID
}
}
...
}
所以在我看来,我添加了以下视图配置:
viewConfig: {
refreshSelmodelOnRefresh:true // Workaround : if this is not set to true when the grid will refresh and a record will be selected we will get an ext error
},
这解决了引发的错误,但我不确定最终结果以及它可能会在以后造成的伤害。
如果有人可以遮挡一些光......
是否有解决方法?
答案 0 :(得分:1)
你可以做一些事情 -
将pageSize增加到至少100,缓冲商店并非真正设计用于小型记录集
使用以下覆盖:
当存储是缓冲类型时,此覆盖修复了多个错误并修复了导致初始hasId无法工作的错误,因为store.getById()方法需要ID而不是记录,同时也强制进行双重验证找不到,因为它将两个检查都放在一个if语句中。
Ext.override(Ext.selection.Model, {
storeHasSelected: function(record) {
var store = this.store,
records,
len, id, i, m;
if (record.hasId()) {
return store.getById(record.getId());
} else {
if (store.buffered) {//on buffered stores the map holds the data items
records = [];
for (m in store.data.map) {
records = records.concat(store.data.map[m].value);
}
} else {
records = store.data.items;
}
len = records.length;
id = record.internalId;
for (i = 0; i < len; ++i) {
if (id === records[i].internalId) {
return true;
}
}
}
return false;
}
});
如果1和2都不起作用,请尝试:
Ext.view.AbstractView.override({
refresh: function() {
var me = this,
targetEl,
targetParent,
oldDisplay,
nextSibling,
dom,
records;
if (!me.rendered || me.isDestroyed) {
return;
}
if (!me.hasListeners.beforerefresh || me.fireEvent('beforerefresh', me) !== false) {
targetEl = me.getTargetEl();
records = me.getViewRange();
dom = targetEl.dom;
// Updating is much quicker if done when the targetEl is detached from the document, and not displayed.
// But this resets the scroll position, so when preserving scroll position, this cannot be done.
if (!me.preserveScrollOnRefresh) {
targetParent = dom.parentNode;
oldDisplay = dom.style.display;
dom.style.display = 'none';
nextSibling = dom.nextSibling;
targetParent.removeChild(dom);
}
if (me.refreshCounter) {
me.clearViewEl();
} else {
me.fixedNodes = targetEl.dom.childNodes.length;
me.refreshCounter = 1;
}
// Always attempt to create the required markup after the fixedNodes.
// Usually, for an empty record set, this would be blank, but when the Template
// Creates markup outside of the record loop, this must still be honoured even if there are no
// records.
me.tpl.append(targetEl, me.collectData(records, me.all.startIndex));
// The emptyText is now appended to the View's element
// after any fixedNodes.
if (typeof records !== 'undefined' && records !== undefined && records && records.length < 1) {
// Process empty text unless the store is being cleared.
if (!this.store.loading && (!me.deferEmptyText || me.hasFirstRefresh)) {
Ext.core.DomHelper.insertHtml('beforeEnd', targetEl.dom, me.emptyText);
}
me.all.clear();
} else {
me.collectNodes(targetEl.dom);
me.updateIndexes(0);
}
// Don't need to do this on the first refresh
if (me.hasFirstRefresh) {
// Some subclasses do not need to do this. TableView does not need to do this.
if (me.refreshSelmodelOnRefresh !== false) {
me.selModel.refresh();
} else {
// However, even if that is not needed, pruning if pruneRemoved is true (the default) still needs doing.
me.selModel.pruneIf();
}
}
me.hasFirstRefresh = true;
if (!me.preserveScrollOnRefresh) {
targetParent.insertBefore(dom, nextSibling);
dom.style.display = oldDisplay;
}
// Ensure layout system knows about new content size
this.refreshSize();
me.fireEvent('refresh', me);
// Upon first refresh, fire the viewready event.
// Reconfiguring the grid "renews" this event.
if (!me.viewReady) {
// Fire an event when deferred content becomes available.
// This supports grid Panel's deferRowRender capability
me.viewReady = true;
me.fireEvent('viewready', me);
}
}
}
});
答案 1 :(得分:1)
在我的代码中,我使用带有网格的缓冲区存储,然后我收到此错误。
我用这个解决了它
selModel: {
pruneRemoved: false
}
答案 2 :(得分:0)
请尝试此覆盖
Ext.data.Store.override({
getById: function(id) {
var result = (this.snapshot || this.data).findBy(function(record) {
return record.getId() === id;
});
if (this.buffered && !result) {
return [];
}
return result;
}
});
答案 3 :(得分:0)
对于ExtJS 5,覆盖BufferedStore而不是Store:
Ext.data.BufferedStore.override({
getById: function(id) {
var result = (this.snapshot || this.data).findBy(function(record) {
return record.getId() === id;
});
if (this.buffered && !result) {
return [];
}
return result;
}
});
答案 4 :(得分:0)
您不需要使用上述任何替代。如果在使用缓冲存储时出现此错误,只需设置此处指定的pruneRemoved:false属性: http://docs.sencha.com/extjs/4.2.3/#!/api/Ext.selection.Model-cfg-pruneRemoved
e.g。
selModel: Ext.create('Ext.selection.RowModel', {
pruneRemoved: false
})