PDA

View Full Version : Grid panel: new items not shown on refresh



Epsitec
6 Aug 2012, 11:59 PM
Hi,

I have a problem in my application. I'm not sure if I'm doing something wrong or if this is a bug in ExtJs. Any help would be greatly appreciated. By the way, I'm using ExtJs 4.1.1 and I tested the application on windows with up to date versions of Firefox and Chrome.

So, here's the problem. In my app, I have a grid panel that displays a list of item that it gets from the server. There are buttons to add a new item, remove an existing item and refresh the grid panel. The add and remove operation are performed on the server with an ajax request and the grid panel is refreshed afterwards to update the display with the new data.

Usually, everything works as expected : the add button adds a new item which is displayed, the delete button deletes the item and the refresh button updates the display if the data has changed on the server.

But sometimes, when I click the add button, the new item is not displayed in the grid panel. The ajax request that adds the data is done properly, the store makes the ajax request to update its data. If the grid panel has a vertical scroll bar, the scroll grip (not sure if that's the proper name for that) shrinks a little, which indicates that something knows that there is a new item, and I can scroll all the way down to see a row with nothing in it. If this happens, a click on the refresh button does not update the view. The ajax request is done to the server, but the view is not updated. The only way to view all the data is to refresh the entire page.

This problem happens only if I have too few items in the dataset. For instance, the problem happens consistently as long as the dataset has less than x items. As soon as there are x + 1, the problem stops. I the count drops to x, it happens again. Now, this 'x' number is not fixed. It seems that it is somehow related to the height of the window. If I have a window of a given size, this 'x' is always the same. If I make the window bigger, 'x' becomes bigger. If I make the window smaller, 'x' becomes smaller.

I have made a small demo application that have the same problem. Here are some screenshots to show what happens :

1) I've got a list with 34 items
37769
2) I click 3 times on the add button. We can see that the scroll grip is smaller and has been moved up a little, which indicates that 3 rows should have been added.
37770
3) When I scroll to the bottom, the 3 rows where the new items should be are totally blank. A click on refresh does not updates the data in these 3 blank rows.
37771
4) A click to add a new item adds the new item and displays it as well as the three rows that where blank before. So in our case the value of 'x' is 37. From now, every click to add will behave as expected, until I remove enough items to have only 37 or less items in the dataset.
37772

Also, here is the complete code for this application demo application. I have not included the server code. It simply have a counter that is incrmented and decremented by requests to demo/add and demo/remove. A request to demo/get gives back as many items as the counter in json, for instance : { items: [{text: '0'}, {text: '1'}], count: 2 }.


Ext.Loader.setConfig({
enabled: true
});

Ext.application({
name: 'Demo',

requires: [
'Demo.TestList',
'Demo.TestListItem'
],

launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'border',
items: [
Ext.create('Demo.TestList', {
region: 'center'
})
]
});
}
});

Ext.define('Demo.TestList', {
extend: 'Ext.grid.Panel',

columns: [
{
xtype: 'rownumberer',
width: 35
},
{
text: 'Text',
flex: 1,
dataIndex: 'text'
}
],

constructor: function(options) {
options.store = this.getStore();
options.tbar = this.getTBar();
this.callParent([options]);
return this;
},

getStore: function() {
return Ext.create('Ext.data.Store', {
model: 'Demo.TestListItem',
pageSize: 100,
remoteSort: true,
autoLoad: true,
buffered: true,
proxy: {
type: 'ajax',
url: 'demo/get',
reader: {
type: 'json',
root: 'items',
totalProperty: 'count'
}
}
});
},

refreshStore: function() {
this.store.reload();
},

addItem: function() {
Ext.Ajax.request({
url: 'demo/add',
method: 'GET',
callback: this.refreshStore,
scope: this
});
},

removeItem: function() {
Ext.Ajax.request({
url: 'demo/remove',
method: 'GET',
callback: this.refreshStore,
scope: this
});
},

getTBar: function() {
var buttonAdd, buttonRemove, buttonRefresh;

buttonAdd = Ext.create('Ext.Button', {
text: 'Add',
listeners: {
click: this.addItem,
scope: this
}
});

buttonRemove = Ext.create('Ext.Button', {
text: 'Remove',
listeners: {
click: this.removeItem,
scope: this
}
});

buttonRefresh = Ext.create('Ext.Button', {
text: 'Refresh',
listeners: {
click: this.refreshStore,
scope: this
}
});

return [buttonAdd, buttonRemove, buttonRefresh];
}
});

Ext.define('Demo.TestListItem', {
extend: 'Ext.data.Model',

fields: [
{
name: 'text',
type: 'string'
}
]
});

Thanks a lot in advance,
Marc

scottmartin
14 Aug 2012, 11:09 AM
Please try using store.load() in refreshStore

Scott.

Epsitec
15 Aug 2012, 1:57 AM
Thanks for your suggestion. I tried it and it corrects the problem described above.

However, it introduces two new problems that happen sometimes and that I never had before :
1) If I add a new row to the list and I scroll all the way down, the scroll bar bounces up before reaching the last element.
2) If I delete a row from the list, it looks fine but when I select the row at the position of the one that was deleted, the row that is obtained with the Ext.grid.Panel.getSelectionModel().getSelection() method is the one that has been deleted.

Moreover, when I call load() on the store, the scroll position is reset to the top but when I call reload() the scroll position is maintained.

I tried to completely replace the store by using the Ext.grid.Panel.reconfigure() with a new store and it seems that it works, except that the scroll position is reset to the top instead of being maintained. So it works, but it gives me the feeling that this is a bit overkill for what I want to do.

scottmartin
15 Aug 2012, 7:51 AM
Can you use Ext.grid.View::preserveScrollOnRefresh

Scott.

Epsitec
16 Aug 2012, 4:54 AM
Thanks again for your suggestion. I tried to set this property to true, but it does not seem to have any effect when I use the load() method on the store or the reconfigure() method on the grid panel. The behavior remains the same.

However, I discovered that if I call removeAll() or pageMap.clear() and then load() on the store, I don't have the 2 problems described in my last post above. So there's only this problem of scroll position left. I'll see if I find something to solve that.