PDA

View Full Version : store.sync does not trigger request on proxy



toirl
29 May 2013, 2:42 AM
Hi,

This is my first post on the forum here and I am quite new to ExtJS at all. I am currently trying to get CRUD actions to work on grids in connection with a restful proxy.
Initial loading the data from the server into my store to fill the grid works.

But when i try to update or delete a record in the store there is no request sent to the server at all after calling store.sync().

However the grid gets updated and the recored was removed or updated. The store also seems to be dirty as store.getRemovedRecored and store.getModifierdRecords returns my recored. So I think the store should "know" all he needs to be able to trigger the sync.

I am trying to get this work since the last two days and after reading several posts here and on stackoverflow I am stuck and asking for your help now.

Here are some code snippets:

The model:

"id" is the primary key in the database, which make a kommetar unique.
Tried to define the proxy at in the store to but this does not afte any effect. Also defining a api in the proxy to provide alternative url to call on the different actions does not have any effect.


Ext.define('Lada.model.Kommentar', {
extend: 'Ext.data.Model',
fields: [
{name: "id"},
{name: "kid"},
{name: "probeId"},
{name: "erzeuger"},
{name: "kdatum"},
{name: "ktext"}
],
proxy: {
type: 'rest',
appendId: true, //default
url: 'server/rest/kommentare',
reader: {
type: 'json'
}
},
idProperty: "id"
});

The Store:


Ext.define('Lada.store.Kommentare', {
extend: 'Ext.data.Store',
model: 'Lada.model.Kommentar'
});

The Grid:


Ext.define('Lada.view.kommentare.List' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.kommentarelist',
store: 'Kommentare',
viewConfig: {
maxHeight: 350,
emptyText: 'Keine Kommentare gefunden.',
// minHeight and deferEmptyText are needed to be able to show the
// emptyText message.
minHeight: 35,
deferEmptyText: false
},
initComponent: function() {
this.dockedItems = [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
text: 'Hinzufügen',
icon: 'gfx/plus.gif',
action: 'add'
},
{
text: 'Löschen',
icon: 'gfx/minus.gif',
action: 'delete'
}
]
}
];
this.columns = [
{header: 'Id', dataIndex: 'id'},
{header: 'Erzeuger', dataIndex: 'erzeuger'},
{header: 'Datum', dataIndex: 'kdatum'},
{header: 'Text', dataIndex: 'ktext', flex: 1}
];
this.callParent(arguments);
}
});

The controller:


Ext.define('Lada.controller.Kommentare', {
extend: 'Ext.app.Controller',
views: [
'kommentare.List',
'kommentare.Edit'
],
stores: [
'Kommentare'
],
models: [
'Kommentar'
],
init: function() {
console.log('Initialising the Kommentare controller');
this.control({
// CSS like selector to select element in the viewport. See
// ComponentQuery documentation for more details.
'kommentarelist': {
// Map Doubleclick on rows of the probenlist.
itemdblclick: this.editKommentar
},
'kommentarelist toolbar button[action=add]': {
click: this.addKommentar
},
'kommentarelist toolbar button[action=delete]': {
click: this.deleteKommentar
}
});
},
addKommentar: function(button) {
console.log('Adding new Kommentar');
},
deleteKommentar: function(button) {
// Get selected item in grid
var grid = button.up('grid');
var selection = grid.getView().getSelectionModel().getSelection()[0];
console.log("Searching grid");
Ext.MessageBox.confirm('Löschen', 'Sind Sie sicher?', function(btn){
if(btn === 'yes'){
var store = grid.getStore();
store.remove(selection);
store.sync();
console.log('Deleting Kommentar');
} else {
console.log('Cancel Deleting Kommentar');
}
});
},
editKommentar: function(grid, record) {
console.log('Double click on ' + record.get('id'));
// Create new window to edit the seletced record.
var view = Ext.widget('kommentaredit');
var form = view.down('form');
form.loadRecord(record);
}
});




Any help is highly welcome!

best
Torsten

Farish
29 May 2013, 3:18 AM
I tried it with the simplified code below (borrowed from the API docs) and it seems to work fine. What you can try is that, for the id field in your model, use type 'int':

{name: "id", type: "int"}

See if this makes a difference but i doubt it will help since its working fine in the example below:


var model = Ext.define('ModelSimpsons', {
extend: 'Ext.data.Model',
fields: [
{name: "id"},
{name: "name"},
{name: "email"},
{name: "phone"}
],
proxy: {
type: 'rest',
appendId: true, //default
url: 'asdf',
reader: {
type: 'json'
}
},
idProperty: "id"
});

var store = Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
model:'ModelSimpsons',
autoLoad: false
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{ text: 'Name', dataIndex: 'name' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone' }
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});

var data = [
{ 'id': '1', 'name': 'Lisa', "email":"lisa@simpsons.com", "phone":"555-111-1224" },
{ 'id': '2', 'name': 'Bart', "email":"bart@simpsons.com", "phone":"555-222-1234" },
{ 'id': '3', 'name': 'Homer', "email":"home@simpsons.com", "phone":"555-222-1244" },
{ 'id': '4', 'name': 'Marge', "email":"marge@simpsons.com", "phone":"555-222-1254" }
];
store.loadData(data);

//store.first().set('name', 'F'); // update
store.remove(store.first()); // delete
store.sync();

toirl
29 May 2013, 4:15 AM
Thanks for your reply Farish.
I can confirm that the simplyfied example does work for be too. There is some delete request fired.

But as you expected providing the type for the "id" field does not change anything and my code still does not trigger any request :(

toirl
29 May 2013, 4:53 AM
Well, after seeing the example from Farnish actually works I tried to "merge" the example with my code. After some tries it seems that I could isolate the part of the code which make the difference:

The store works as expected if I fill it using the loadRecord function:


// Load kommentare
var data = [
{"id":780,"probeId":"0000075","erzeuger":"12020","kdatum":1323866213000,"ktext":"xxx","kid":190604},
{"id":465,"probeId":"0000075","erzeuger":"06010","kdatum":1321005677000,"ktext":"xxx","kid":188653},
{"id":466,"probeId":"0000075","erzeuger":"06010","kdatum":1321005682000,"ktext":"xxx","kid":188654},
{"id":467,"probeId":"0000075","erzeuger":"12020","kdatum":1334134920000,"ktext":"xxx","kid":202132},
{"id":468,"probeId":"0000075","erzeuger":"12020","kdatum":1334135220000,"ktext":"xxx","kid":202147}];
var kommentare = form.down('kommentarelist'); //form.down('kommentare');
var kstore = kommentare.getStore();
kstore.loadData(data);


but it does not work if I fetch the data from the server:


var kommentare = form.down('kommentarelist');
form.down('kommentare');
var kstore = kommentare.getStore();
kstore.load({
params: {
probe: record.data['probeId']
}
});

So the question is: Where is the difference?

Farish
29 May 2013, 4:55 AM
when the store is loaded from the server, print out the records which have been fetched and compare them with the array (which you load directly). see whats the difference between the two.

toirl
29 May 2013, 6:34 AM
Well, I finally got working... This is the good part of the message. But I don't now why.

While merging the code I did several changes and thought that I found the place in code which make the difference. But this was not true as the application still works after using the load function instead of the loadData function again.

So the difference must be elsewhere or I am runnig in some weird caching thing or whatever.

Unfortunatly I did not commit the last non-working version to get a diff to the working version, so I must must left out the clearing answer which bits makes the difference... for now.

I will mark this question as answerd, but I try to add the difference here.