PDA

View Full Version : Model-Store-Proxy-Reader not working for me



stefan_k
5 Dec 2010, 8:28 AM
Hi guys,

I'm trying to get my head around the whole Model-Store-Proxy-Reader thing. Even though I am able to work with a single model in my application, I am not able to work with different models and different stores. Maybe someone can push me into the right direction.

Here is what I do. First, I register a new application:


new Ext.Application({
name: 'CP',
launch: function() { ... }
});


Everything is done in the launch method. After that, I register two models:


CP.models.speaker = Ext.regModel('Speaker', {
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
],
associations: [
{ type: 'hasMany', model: 'Session', name: 'sessions' }
],
proxy: {
type: 'localstorage',
id: 'speakers'
}
});

CP.models.session = Ext.regModel('Session', {
fields: [
{ name: 'id', type: 'int' },
{ name: 'speaker_id', type: 'int' },
{ name: 'title', type: 'string' }
],
associations: [
{ type: 'belongsTo', model: 'Speaker' }
],
proxy: {
type: 'localstorage',
id: 'sessions'
}
});


After that, I register two stores:


CP.stores.speaker = Ext.regStore('Speakers', {
model: 'Speaker',
data: speaker,
autoload: true,
proxy: {
type: 'memory',
reader: {
type: 'json',
}
}
});

CP.stores.session = Ext.regStore('Sessions', {
model: 'Session',
data: session,
autoload: true,
proxy: {
type: 'memory',
reader: {
type: 'json'
}
}
});


I then create a new Ext.List that shows all the various speakers from the Speakers store:


var list = new Ext.List({
store: 'Speakers',
itemTpl: '{name}',
fullscreen: true
}, Ext.getBody());


So far so good, this works perfectly. What I want to do now is to listen for an item tapped in the list. After the tap, I want to access all sessions that are associated with this speaker. Therefore, I add this to the list config:


listeners: {
itemtap: function(view, index, item, e) {
var record = view.getStore().getAt(index);
record.sessions().load({
callback: function(records, operation) {
console.log(records);
}
}
}
}


Unfortunately, this prints out an empty array instead of the associated sessions. What am I missing? Any help is greatly appreciated, I have been trying to get this to work for the last couple of days. I tried it with Sencha Touch v1.0.0 and v1.0.1.

Here is some very simple dummy data that I used to test this:


var speaker = [
{ id: 1, name: 'John Doe' }
];

var session = [
{ id: 1, speaker_id: 1, title: 'My Session'}
];


Thank you

Animal
5 Dec 2010, 12:11 PM
Deubg.

Step into the Store creation, and see why it's not loading.

stefan_k
6 Dec 2010, 1:09 AM
Animal, thanks for the reply. I did that and I don't think that this is the problem. Both stores load their data just fine. In fact, if I change the store used within the list to Sessions, and change the itemTpl to {title}, I see the title of the sessions. So both stores seem to have data in them.

Any other suggestions?

Animal
6 Dec 2010, 1:31 AM
Set a break at



callback: function(records, operation) {
console.log(records); // <-- here


And go back through the call stack to see why the records Array is empty/ Who is setting it to what and why.

And if you don't see how they do it, set a breakpoint in that code at the point that does the work, and re-run it.

stefan_k
6 Dec 2010, 8:16 AM
Oh boy, after several hours of debugging today and trying to understand what is going on under the hood of Sencha, I am still not able to get this to work. Here is what I found out:

Ext.data.Store.load is called and a couple of options are set. Additionally, a callback function is registered (in this case, the function that does the console.out() of the records).
On the superclass of Ext.data.Store, which is Ext.data.AbstractStore, the load method is called; A couple of options are set; A new Ext.data.Operation object is instantiated (this will be returned and should hold the data read from an associated store).
The registered proxy, i.e. Ext.data.WebStorageProxy, is called to read the data and I think here the whole thing breaks. In the second row of Ext.data.WebStorageProxy.read(), this.getIds() is called, which, in my understanding, should read the IDs of the records that should be added to the resultSet of the operation. But instead, this.getIds() is empty.

Hopefully, someone can make sense of this. Any hint, idea, suggestions is greatly appreciated.

stefan_k
7 Dec 2010, 4:23 AM
Finally, I am starting to make some progress in this matter. I am now able to retrieve sessions after I tap on a speaker's list entry. But instead of sessions that are associated with the selected speaker, the array sessions in the callback function holds all available sessions, no matter with which speaker they are associated. Do I have to do the filtering myself? I thought that the automatically generated sessions() method is responsible for doing this?! Any thoughts on this?

Here is the altered code I am using:



new Ext.Application({
name: 'CP',
launch: function() {
var speakers = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' }
];
var sessions = [
{ id: 1, speaker_id: 1, title: 'John\'s session' },
{ id: 2, speaker_id: 2, title: 'Jane\'s session' }
];

CP.models.session = Ext.regModel('Session', {
fields: [
{ name: 'id', type: 'int' },
{ name: 'speaker_id', type: 'int' },
{ name: 'title', type: 'string' }
],
associations: [
{ type: 'belongsTo', model: 'Speaker' }
],
proxy: {
type: 'localstorage',
id: 'CP.proxy.session'
}
});

CP.models.speaker = Ext.regModel('Speaker', {
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
],
associations: [
{ type: 'hasMany', model: 'Session', name: 'sessions' }
],
proxy: {
type: 'localstorage',
id: 'CP.proxy.speaker'
}
});

CP.stores.speaker = Ext.regStore('SpeakerStore', {
model: 'Speaker'
});

CP.stores.session = Ext.regStore('SessionStore', {
model: 'Session'
});

var speakerStore = Ext.getStore('SpeakerStore');
speakerStore.getProxy().clear();
speakerStore.add(speakers);
speakerStore.sync();

var sessionStore = Ext.getStore('SessionStore');
sessionStore.getProxy().clear();
sessionStore.add(sessions);
sessionStore.sync();

var list = new Ext.List({
fullscreen: true,
store: 'SpeakerStore',
itemTpl: '{name}',
listeners: {
itemtap: function(view, index, item, e) {
var speaker = view.getStore().getAt(index);
speaker.sessions().load({
callback: function(sessions, operation, success) {
console.log(sessions);
}
});
}
}
}, Ext.getBody());
}
});