PDA

View Full Version : Problem with grid and state management



tm8747a
15 Sep 2014, 12:53 PM
I have a very strange issue that happens sporadically. Unfortunately this is going to be a rather crappy description of the problem because I can't replicate it and I don't see an exact pattern, but am hoping somebody might recognize it as something that's happened to them.

Basically, I have a grid and am saving its state using a custom state provider that I've created to save to a database. Bear in mind I have no idea if the state provider is actually related to the problem or not. The grid columns are dynamic and as such depending on the scenario (settings and such) there may be more or less columns. What I've noticed is that at times the grid shows up and the column alignment is messed up, the data columns are not aligned with the header columns, if it's an editable grid sometimes clicking on a cell actually opens a selector in a different cell, etc. When that happens, the only way for me to fix the grid is to clear out the state provider of the value saved for that grid.

The following is an override I have for columns, it basically makes the dataIndex the state ID if no stateID is specified before relying on the headerId. I added this because I was running into problems with columns being confused for other colums when new columns got added because the headerId just get all messed up and then sorting is off, etc.



Ext.define('overrides.grid.column.Column', {
override: 'Ext.grid.column.Column',

getStateId: function () {
return this.stateId || this.dataIndex || this.headerId;
}
});


The following is my DB provider. It's pretty simple, MyApp.Config.getUserSettings() just gets settings that have been preloaded when the app starts and saves them in the state property. MyApp.Config.saveUserSetting() does an Ajax request to save state to the server, and since it's also calling the parent function, it stores the change locally as well.



Ext.define('Ext.state.DBProvider', {
extend: 'Ext.state.Provider',

requires: ['MyApp.Config'],

constructor: function(cfg){
// Call the abstract provider constructor, which will initiate some variables
this.callParent(arguments);
// Populate the state object with data from the Config object
this.state = MyApp.Config.getUserSettings();
},

/**
* Saves a name/value pair for state to the database
*/
set: function(name, value){
// Only save a setting if it has changed
if (Ext.JSON.encode(value) != Ext.JSON.encode(this.state[name])) {
// Use the Config object to save the state in the database
MyApp.Config.saveUserSetting(name, value);
// Call the abstract provider's set() function to save the name/value pair in the state object
this.callParent(arguments);
}
}
});

slemmon
14 Oct 2014, 2:39 AM
Supporting custom state providers will be a bit out of scope, though I'm curious what happens when you just use a cookie state provider.

tm8747a
25 Nov 2014, 9:18 AM
Attached is an example of the problem I'm talking about. Notice how the data from Location column and onwards is not in the right place? Everything gets shifted to the right for some reason.

51096
And here's the state provider I'm using:



Ext.define('MyApp.DBProvider', {
extend: 'Ext.state.Provider',

requires: ['MyApp.Config'],

constructor: function(cfg){
// Call the abstract provider constructor, which will initiate some variables
this.callParent(arguments);
// Populate the state object with data from the Config object
this.state = MyApp.Config.getUserSettings();
},

/**
* Saves a name/value pair for state to the database
*/
set: function(name, value){
// Only save a setting if it has changed
if (Ext.JSON.encode(value) != Ext.JSON.encode(this.state[name])) {
// Use the Config object to save the state in the database
MyApp.Config.saveUserSetting(name, value);
// Call the abstract provider's set() function to save the name/value pair in the state object
this.callParent(arguments);
}
}
});


All MyApp.Config.getUserSettings() does is pull the state from a local variable that holds the settings (they all get preloaded at app startup). Then MyApp.Config.saveUserSetting() saves the state to the database, and then callParent() is called, which also saves the state locally.

tm8747a
25 Nov 2014, 9:25 AM
Supporting custom state providers will be a bit out of scope, though I'm curious what happens when you just use a cookie state provider.

The challenge here is for me to replicate the problem. It happens pretty randomly and I can't really make it happen on demand. For the example I provided, I took the saved state JSON in my database and saved it to another database and opened the grid, the problem didn't manifest itself. So I'm kind of at a loss. Maybe somebody has an idea at least where I should go digging as far as the positioning of the column data? I'm assuming it's something under Ext.view.Table, but haven't quite been able to pinpoint it yet.

tm8747a
25 Nov 2014, 9:55 AM
I feel I'm getting somewhere, screenshot below shows a discrepancy.
51097

Note that the width style is correctly set at 239px, and yet the width ends up being computed at 283.767px. Does anybody have any clue as to why that would happen?

tm8747a
25 Nov 2014, 1:48 PM
I was finally able to replicate at will, and I was able to do it withe the default cookie provider. See bug thread: http://www.sencha.com/forum/showthread.php?295163-Bug-in-grid-column-sizing-with-state-provider&p=1077605#post1077605