PDA

View Full Version : Help with MVC and ScriptTagProxy



Achim74
2 Jun 2011, 12:57 PM
Hello !

I am trying to create my first MVC app and try to understand the concepts. I did it on my own put had a peek into the twitter example because I have to use a JSONP request. In the twitter example this is done by a json request and ScriptTagProxy.

Unfortunately my script won't work. The request is executed, valid JSON is returned but my dataview does not get filled. I don't know why. When I do a util.JSONP request and update the data view with the data it works !? :(

Does anyone have a hint? Here is my relevant code:


Ext.regStore('TestStore', {
model: 'TestModel',
autoLoad: false
});


Ext.regModel("TestModel", {

fields: [
{name: "icon", type: "string"},
{name: "name", type: "string"},
{name: "position", type: "string"},
],

proxy: 'TestProxy'
});


Ext.data.TestProxy = Ext.extend(Ext.data.ScriptTagProxy, {
url: 'http://localhost/sencha/json.php',

constructor: function(config) {
config = config || {};

console.log('Proxy Constructor');

Ext.applyIf(config, {

extraParams: {
suppress_response_codes: false
},

reader: {
type: 'json',
root: 'results'
}
});

Ext.data.TestProxy.superclass.constructor.call(this, config);
},

buildRequest: function(operation) {

var request = Ext.data.TestProxy.superclass.buildRequest.apply(this, arguments),
filter = operation.filters[0],
params = request.params;

Ext.apply(params, {
rpp: operation.limit,
page: operation.page
});

if (filter) {
Ext.apply(params, {
q: filter.value
});

request.url = this.buildUrl(request);
}

return request;
}
});

Ext.data.ProxyMgr.registerType('TestProxy', Ext.data.TestProxy);

test.views.TestList = Ext.extend(Ext.Panel, {
initComponent: function() {
test.views.TestList.superclass.initComponent.apply(this, arguments);
var TestStore = Ext.getStore('TestStore');
TestStore.filter('q','Stuttgart');

TestStore.load({
scope : this,
callback: function(records, operation, success) {
console.log(records);
}
});

},
scroll: 'vertical',
autoHeight:true,
collapsible:true,
layout:'fit',
items: new Ext.DataView({
store: 'TestStore',
tpl: [
'<tpl for=".">',
'<div class="test">',
'<div class="avatar"><img src="{icon}" /></div>',
'<div class="test-content">',
'<h2>{name}</h2>',
'<p>{position}</p>',
'</div>',
'</div>',
'</tpl>'
],
itemSelector:'div.test',
autoHeight:true,
multiSelect: true,
emptyText: 'No data to display'
})


});

Ext.reg('TestList', test.views.TestList);

Thank you very much !!!

Achim74
2 Jun 2011, 10:14 PM
Can someone help me? Do u need further infos?

hyperionab
3 Jun 2011, 7:32 AM
I know this won't help you that much, but here's a little bit of code I used in a recent project to load a bunch of JSON. It's not the best practice, but might help you get unstuck:



Project.load = function(data, source, written, time) {
Ext.getBody().mask(false, '<div class="loading">Loading&hellip;</div>');
Ext.Ajax.request({
url: 'load.php',
params: {
data: data,
source: source
},
success: function(response, options){
var json = Ext.util.JSON.decode(response.responseText);
if (json.success) {
Project.input.maxRow = json.height;
Project.input.maxCol = json.width;
/* etc etc etc */

Achim74
3 Jun 2011, 10:50 AM
Thank you hyperionab. Every hint is appreciated and welcome. I really got stuck. I even don't know how I could debug it. I will now have a deeper look on the twitter example to se how it differs from my approach. But there is more additional stuff that makes it not easier to understand.

Here is the snippet that worked for me. So at least I know that the JSON is valid and the DataView accepts the data.



Ext.util.JSONP.request({
url: 'http://localhost/sencha/php/json.php',
callbackKey: 'callback',
params: {
q: 'Test',
rpp: 30,
nocache: Math.random()
},
callback: function(data) {
console.log(data);
var myDataView = Ext.getCmp('myDataView');
myDataView.update(data.results);
}
});

Achim74
3 Jun 2011, 11:17 AM
I am one step ahead. In my view I am loading the controller:



TestStore.load({
scope : this,
callback: function(records, operation, success) {
//the operation object contains all of the details of the load operation
console.log('Success '+success);
console.log('Records');
console.log(records);
console.log('Operation');
console.log(operation.response.results);
}
});


success = true, records = undefined!?
operation.response.results is a object with the results ... now the only question is why is that stuff not passed to the dataview? what did i miss?

any help is appreciated .. thank you in advance.


From the sencha blog:
http://www.sencha.com/blog/using-the-data-package-in-sencha-touch


DataView is a component that knows how to use a Store and render the Model instances to HTML using a template. We set the template above using an Ext.XTemplate - our powerful templating class. Once the Store loads its data, the DataView automatically takes each of the loaded records and renders the HTML for it based on the template, giving us a list of rendered products. Now that we have a rendered page of Products, let's take our example a step further and implement a simple Cart. Our Cart is going to be another Store, this time using the session storage proxy to save the user's cart items client-side until they are ready to proceed:


That means I don't have to call update or anything if I have a store bound to the DataView. There must be something incorrect with syntax (got no errors) or scoping. Right now I don't get the point :(

Achim74
3 Jun 2011, 11:50 AM
I am stiff-necked ... hope this is not too annoying:

When I do this in the view:


var myDataView = Ext.getCmp('myDataView');
myDataView.update(operation.response.results);


it works and it fills my DataView .. but I usually don't have to do this, right? It should happen automatically...still trying to figure out.

hyperionab
5 Jun 2011, 9:33 AM
Not totally sure if you have to do that, but there are another few examples that use MVC and JSONP:

https://github.com/senchalearn/teagrams
https://github.com/senchalearn/seattlebars

Hopefully those help too.