PDA

View Full Version : record.set() and updating a grid?



ramonster
8 Dec 2009, 3:24 PM
Hi,

I have tried for hours to get Record.set() to trigger the GridPanel into refreshing the record/grid after changing information. If I sort items in the grid manually (click header) the changed information then appears!

I have 'add' and 'update' set as listeners on the ArrayStore - Record.add() and Record.remove() cause the GridPanel linked to the ArrayStore to refresh and show the change but set()'ting does nothing except silently change the data, and DOES NOT throw an UPDATE event to the store.

Heres the code I'm using to test the set() change at the moment, its basically merging new records from temp_store into store if they don't exist, and if they do, well at least in the code below, it just changes the pos_comment field to "test update!". Note the below doesn't fire the "UPDATE" event in the store, and the grid pos_comment field doesn't change.

Experts - what am I missing??? Have tried with all manner of commit()'s and comment outs etc, thanks in advance! NOTE: I'm using ExtJS 3.03 (latest public release).


function grid_updater() {
temp_store.each(function(rec) {
var i = store.findExact('pos_purchaseid',rec.get('pos_purchaseid'));
if (i==-1) {
store.add(rec);
} else {
var r = store.getAt(i);
r.beginEdit();
r.set('pos_comment','test update!');
r.endEdit();
}
});
store.commitChanges();
store.each(function(rec) { var r = temp_store.findExact('pos_purchaseid',rec.get('pos_purchaseid')); if (r==-1) { store.remove(rec); }});
}

ramonster
8 Dec 2009, 3:49 PM
So I've been looking into this, is it a bug??? From the ExtJS 3.0 API Record section:

"endEdit() : void
End an edit. If any data was modified, the containing store is notified (ie, the store's update event will fire)."

The data is most definitely modified because if I manually click a header and resort it shows, so its modifying just fine, I have a listener on the store set as:


store = new Ext.data.ArrayStore({
fields:
[ {name: 'pos_purchaseid', type: 'int'},
{name: 'pos_myobpurchasenumber', id: 'pos_myobpurchasenumber'},
{name: 'pos_myobsupplierinvoicenumber'},
{name: 'pos_suppliername'},
{name: 'pos_date'},
{name: 'pos_statusid'},
{name: 'pos_comment'}
],

listeners: {'update': function() { alert('!'); },
'add': function() { alert('add!'); }
}
});


The above 'update' listener never fires from Record.endEdit()... help? or bug?

Steffen Hiller
8 Dec 2009, 5:52 PM
Hi ramonster,

try to isolate your problem. Maybe your code doesn't call the set method at all.

Try this:
1. Give your grid an id via the id config option.
2. Open your page in firefox with firebug enabled.
3. Select one row in your grid
4. Enter in the Firefox console: Ext.getCmp('your-grid-id').selModel.selections.items[0].set('pos_comment', 'test update!')
5. The pos_comment field value in the selected row should have been changed now (and have a small red triangle on the top left)
6. Ext.getCmp('your-grid-id').store.commitChanges() removes the triangle.

If that's working as expected, then something with your code, and not with the Ext JS code is wrong.

Hope that helps.

Cheers,
Steffen

Steffen Hiller
8 Dec 2009, 5:54 PM
Btw, you don't need to wrap the set method into beginEdit and endEdit. But removing it still may not solve your problem.

ramonster
8 Dec 2009, 7:00 PM
Thanks very much for the reply and your thoughts Steffen!

Entering Ext.getCmp('your-grid-id').selModel.selections.items[0].set('pos_comment', 'test update!') to the console with a row selected did not prompt the grid view to update, but if I click a header to sort it then displays so its changing fine but not updating the view.

I ended up using the following as a workaround which fixes the issue from the users point of view, but seems strange to me:


var sortee = store.getSortState();
store.sort(sortee.field,sortee.direction);

As an aside, whilst playing with this I notice Record.add() does not honor any sorting in place, which it should imho.

Steffen Hiller
8 Dec 2009, 7:05 PM
Hmm, strange. What version of Ext JS are you using?

How do you bind the store to your grid? Maybe try to remove your update and add listeners. Maybe they are interfering somehow.

ALso, checkout the Store.addSorted method, it honors the current sorting state.

ramonster
8 Dec 2009, 7:24 PM
Hi, thanks again...

Using current public release 3.03, store is defined as:


store = new Ext.data.ArrayStore({
fields:
[ {name: 'pos_purchaseid', type: 'int'},
{name: 'pos_myobpurchasenumber', id: 'pos_myobpurchasenumber'},
{name: 'pos_myobsupplierinvoicenumber'},
{name: 'pos_suppliername'},
{name: 'pos_date'},
{name: 'pos_statusid'},
{name: 'pos_comment'}
]
});

and grid is...


grid = new Ext.grid.GridPanel({
region: 'center',
store: store, etc etc etc etc

Removed the listeners completely , no dice. Adds and updates are fine, just Record.set()'s work - the store updates but the grid does not trigger a refresh. grid.getView().refresh(); after Record.set() works fine, as does resorting. Strange...

Thanks for the heads up on addSort!

Steffen Hiller
8 Dec 2009, 7:31 PM
Hmm, your code looks fine to me.

At least you got it to work somehow, whereas the refresh shouldn't be needed normally.

Look here how it should work:
1. Open http://www.extjs.com/deploy/dev/examples/grid/array-grid.html
2. Enter in firebug console: Ext.ComponentMgr.all.items[0].store.data.items[0].set('company', 'test update!')

This should change the value in the view right?

ramonster
8 Dec 2009, 9:02 PM
Hi, yes that changes the value on the demo, must be just some strange behavior or obscure issue I guess.

qooleot
20 Apr 2010, 5:20 AM
I'm still having this issue with the .set() call. It actually works the first time, but the script then aborts (no other javascript lines below the .set() run).

It actually worked if I put each call in a setTimeout() function. It also works from firebug. That was sort of hacky so I fixed the problem with:



myGrid.getStore().reload({
params: {model: device_model,
device_name: new_device_name}
});
instead of doing .set() for each cell since my editor grid is really a super propertygrid.

Keylan
20 Apr 2010, 8:07 AM
The endEdit and afterEdit functions for record:


endEdit : function(){
this.editing = false;
if(this.dirty){
this.afterEdit();
}
},
afterEdit : function(){
if (this.store != undefined && typeof this.store.afterEdit == "function") {
this.store.afterEdit(this);
}
},
I don't think this is going to result in the functionality you are looking for. Instead of using beginEdit() and endEdit(), I suggest making all your changes and then firing the store's datachanged event afterwards to force the grid to update with the changes.