Sencha touch 2 MVC Store - extjs

Im looking for a tutorial or an example for sencha touch 2 MVC STORE which deals with Jsonp link and fetches data from there, ONLY MVC BASE .I need to learn how Store, Model, Controller and View interact with each other in MVC based structure . any suggestion ? between I need to understand how to fetch and work with jsonp links and datas, Thanks

Download sencha touch 2 and find oreilly example. In this example in About panel Tweets page loads data from store (reader type is jsonp). Also you should check another examples like touchtweets, geocongress, navigationview etc.
I think it's the best way for start.

I have found the documentation has a lot of good tutorials on understanding sencha touch's MVC structure, as well as each individual topics like stores and models.
MVC in depth part 1:
http://docs.sencha.com/touch/2-0/#!/video/mvc-part-1
MVC in depth part 2:
http://docs.sencha.com/touch/2-0/#!/video/mvc-part-2
The docs also have a guide section that goes over everything that you need to know too.
http://docs.sencha.com/touch/2-0/#!/guide

A simple example of model,store and view using jsonp
How jsonp looks like.
callback({"Message":"Success","Post":[{"id":"35","UserId":"faisalkhalid690","Content":"lol","Time":"2013-12-03 05:28:15"},{"id":"50","UserId":"faisalkhalid","Content":"asdfasdfasdf","Time":"2013-12-03 05:52:27"},{"id":"51","UserId":"faisalkhalid","Content":"sadfasdfasdf","Time":"2013-12-03 05:52:38"},{"id":"52","UserId":"faisalkhalid","Content":"holloa","Time":"2013-12-03 05:52:50"},{"id":"70","UserId":"faisalkhalid690","Content":"hello","Time":"2013-12-04 23:22:52"}]});
Model for this jsonp.
Ext.define('talkbag.model.Comments', {
extend: 'Ext.data.Model',
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'auto' },
{ name: 'UserId', type: 'auto' },
{ name: 'Content', type: 'auto' },
{ name: 'Time', type: 'auto' }
]
}
});
Store:
Ext.define('talkbag.store.Comments', {
extend:'Ext.data.Store',
storeId:'Comments',
config:{
autoLoad: true,
model:'talkbag.model.Comments',
proxy: {
type: 'jsonp',
url : 'http://www.litemake.com/ViewComments.php?Pid='+talkbag.User.PostId,
reader: {
type: 'json',
rootProperty: 'Post'
}
}
}
});
View:
Ext.define('talkbag.view.ViewPost.ViewCommentDetail', {
xtype:'ViewCommentDetail',
extend:'Ext.dataview.List',
config:{
store:'Comments',
itemTpl:'<table><tr><td width="80px"><table align="center"><tr><td align="center"><img src="http://www.litemake.com/getPic.php?userId={UserId}" heigth="30px" width="30px"/></td></tr><tr><td style="font-size:0.6em">{UserId}</td></tr></table></td><td style="padding-left:20px"><table><tr><td style="font-size:0.7em; padding:0px 0px 5px 0px">{Content}</td></tr><tr><td style="font-size:0.5em">{Time}</td></tr></table></td></tr></table>'
}
});

If you need some information about JSONP - Server Side, then have a look to
the Sencha Touch API (JSONP)
There you can find serverside methods to handle your JSONP request for common server side programm languages like PHP, Java or ASP.net.
For PHP it would look like this:
// From your Sencha JSONP Store, you will get a callback parameter which we
// need to put in our $callback var, for later usage.
$callback = $_REQUEST['callback'];
// Create the output object.
// this could also be a database output, but remember to
// convert it into an array
$output = array('a' => 'Apple', 'b' => 'Banana');
// start output
// this section switches between a jsonp callback or usual json output.
if ($callback) {
header('Content-Type: text/javascript');
echo $callback . '(' . json_encode($output) . ');';
} else {
header('Content-Type: application/x-json');
echo json_encode($output);
}
As Faisal Khalid already said, the output will look like...
myCallbackName({
"message":"success",
"total":2,
"data":[
{"prename":"Bob","lastname":"example"},
{"prename":"John","lastname":"Beard"}
]
});
... where you've defined myCallbackName as the callback name in your sencha application (store configuration).
The config is called callbackKey and is set to callback by default.

Related

How can I share model methods between the client and the server in loopback?

I want to share some business logic both on the client and the server.
Let's say it is a file API, and I want to know if an item has a type of folder.
On the server it looks like this:
Content.prototype.isFolder = function() {
return this.type === 'folder';
}
Is it currently possible to expose this in an easy manner to the client?
We are also using loopback-sdk-angular. Integrating with that is the ultimate goal.
What is the best way to do this?
You can use browserify.
You can create a shared library that has the isFolder method, and use this both on the server, and the browserified version on the client.
How you easily integrate that with angular is another question.
I would suggest to create a new remote method, to expose it to the REST API:
Model.remoteMethod(
'isFolder',
{
http: { path: '/isFolder', verb: 'get' },
accepts: [
{
arg: 'id',
type: 'string',
required: true,
http: {
source: 'query'
}
},
],
returns: { arg: 'isFolder', type: 'boolean' }
}
);
Use the common directory at the project root. See http://docs.strongloop.com/display/public/LB/common+directory

ExtJS Web Sockets: Ext.ux.WebSocket eventName error

I'm using the Ext.ux.data.proxy.WebSocket extension, and have the following store definition:
Ext.define('ExtMVC.store.StatsWebSocket', {
extend: 'Ext.data.Store',
alias: 'store.statswebsocket',
requires: [
'Ext.ux.data.proxy.WebSocket'
],
model: 'ExtMVC.model.Stock',
proxy: {
type: 'websocket',
storeId: 'StatsWebSocket',
url: 'ws://localhost:8087/ws',
reader: {
type: 'json',
root: 'cis4-file-stats'
}
}
});
Using Chrome debugger, I can see that the data is actually retrieved but somehow it doesn't end up in my Grid. The point where the store is used in the grid is shown below:
initComponent: function(){
var store = Ext.create('ExtMVC.store.StatsWebSocket');
Ext.apply(this, {
height: this.height,
store: store,
....
I've followed the instructions at [URL]https://market.sencha.com/extensions/ext-ux-data-proxy-websocket[/URL], but nothing seems to work. Any idea what I may be doing wrong? Thanks in advance.
Every time the browser receives data from the socket server, the error:
Uncaught Ext.ux.WebSocket.receiveEventMessage(): (No description provided)
is thrown.
The error occurs in this function of the Ext.ux.WebSocket extension:
fireEventArgs: function(eventName, args) {
eventName = eventName.toLowerCase(); // ERROR occurs here
var me = this,
events = me.events,
event = events && events[eventName],
ret = true;
if (event && me.hasListeners[eventName]) {
ret = me.continueFireEvent(eventName, args || emptyArray, event.bubble);
}
return ret;
}
Environment: ExtJS 4.1, Netty 3.5.0.Final.
FYI: I've also posted this question here.
UPDATE:
My question has been answered on the Sencha Forum by the developer of the extension, Wilky. In a nutshell, the JSON retured by the socket server must conform to a specific structure. It must have 'event' and 'data' nodes:
{"event": "read", "data": [{....}, {....}]}
"event" can be any of the CRUD methods; read, update, destroy or create. "data" corresponds to your application-specific data. All I needed to do was alter the structure of my JSON data.
I don't know if it has anything to do with your problem but I don't think the storeId definition inside
the proxy would work. Generally it should be defined as a config option of the store, but in your case you use it inside a proxy, which is defined in the store, so you don't need it at all.

Ext.data.proxy.Ajax and WCF services via JSON

I'm trying to make ExtJs work with backend running WCF RIA services with JSON endpoint enabled. The backend I have uses GetXXX for read data and CommitChanges for create/update/delete data. It also has not ExtJs standard message format, so I have store class defined like this:
function cloneObject(src, dst) {
for (var key in src)
{
dst[key] = src[key];
}
return dst;
}
Ext.define('MyApp.store.Items', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Tax',
autoLoad: true,
autoSync: true,
proxy: {
type: 'ajax',
api: {
read: '/MyApp/MyAppWeb-Web-MyAppDomain.svc/JSON/GetItems',
update: '/MyApp/MyAppWeb-Web-MyAppDomain.svc/JSON/SubmitChanges',
create: '/MyApp/MyAppWeb-Web-MyAppDomain.svc/JSON/SubmitChanges',
destroy: '/MyApp/MyAppWeb-Web-MyAppDomain.svc/JSON/SubmitChanges'
},
reader: {
type: 'json',
root: 'GetItemsResult.RootResults',
successProperty: null,
totalProperty: 'GetItemsResult.TotalCount'
},
writer: {
type: 'json',
root: 'changeSet',
currentOperation: null,
getRecordData: function(record) {
var changeSet = [];
var entity = {
Id: 0,
Operation: 3,
Entity: {
__type: 'Items:#MyApp.Web'
},
OriginalEntity: {
__type: 'Items:#MyApp.Web'
}
};
cloneObject(record.data, entity.Entity);
cloneObject(record.raw, entity.OriginalEntity);
changeSet.push(entity);
return changeSet;
}
}
}
});
As you can in order to accomodate Microsoft JSON endpoint format I had to override getRecordData and create custom JSON object. I can probably replace cloneObject function with merge function, right? (I'm still kind of new to ExtJs, so may be I'm trying to "invent a bicycle" here.
It works more or less as expected for update, however for create and delete I need to create slightly different message format. Different Operation code and no need to send OriginalEntity. However inside getRecordData I don't have information about what kind of operation is being performed. So question #1
What is the best approach here? Override 'write' method as well or is there another way?
Question #2. After any update standard store class would call reader in order to parse response, but response for update is very different then response for GetItems and I have no idea how to handle that.
Any suggestions or links to walk-through on how to tie ExtJs and Domain Services?
I ended up re-writing Proxy class to add support for different parsing for read/write operations. Works pretty well. Let me know if somebody else faces same problems - I will post code samples.

extjs4 - is there a non json/xml writer for proxies?

I'm building some models to interact with an existing API from a previous project.
The API relies on standard POST methods to save the data.
I've configured a model and proxy up to the point where it does push the data onto the server but there only seems to be two writer types, json & xml.
proxy: {
/* ... */
reader: {
type: 'json',
root: 'results'
},
writer: {
type: '???' // <-- can only see json or xml in the docs
}
}
Isn't there a standard POST writer that simply submits data in post fields?
I'm surprised that wouldn't be a standard writer type.
(Parsing the json format wouldn't be too hard to implement but that would mean updating a lot of the old api files.)
Ok, I was able to create that writer quite easily by checking the existing writers' source code.
One thing those existing writers are able to do - and that may be why the dev team only implemented a json and xml version - is that they can push multiple records at once.
That could be implemented in POST but would be a bit more complicated.
This writer will work if you're trying to push a single model to an api using POST:
Ext.define('Ext.data.writer.SinglePost', {
extend: 'Ext.data.writer.Writer',
alternateClassName: 'Ext.data.SinglePostWriter',
alias: 'writer.singlepost',
writeRecords: function(request, data) {
request.params = data[0];
return request;
}
});
and the use this for the writer in the proxy:
writer: {
type: 'singlepost'
}
Based on Ben answer I've implemented my own writer that will collect all properties of all models into arrays.
For example if you have model like with some fields:
fields:[
{name:'id', type:'int'}
{name:'name', type:'string'}
{name:'age', type:'date'}
]
A request string will be
id=1&id=2&id=...&name=oleks&name=max&name=...&age=...
Code:
Ext.define('Ext.data.writer.SinglePost', {
extend: 'Ext.data.writer.Writer',
alternateClassName: 'Ext.data.SinglePostWriter',
alias: 'writer.singlepost',
writeRecords: function(request, data) {
if(data && data[0]){
var keys = [];
for(var key in data[0]){
keys.push(key);
}
for(var i=0;i<keys.length;i++){
request.params[keys[i]] = [];
for(var j=0;j<data.length;j++){
request.params[keys[i]].push((data[j])[keys[i]]);
}
}
}
return request;
}
});
For Sencha touch 2.0, change the writeRecords method to:
writeRecords: function (request, data) {
var params = request.getParams() || {};
Ext.apply(params, data[0]);
request.setParams(params);
return request;
}
Here's my version, adapted from answers above:
// Subclass the original XmlWriter
Ext.define('MyApp.utils.data.writer.XmlInAPostParameter', {
extend : 'Ext.data.writer.Xml',
// give it an alias to use in writer 'type' property
alias : 'writer.xml_in_a_post_parameter',
// override the original method
writeRecords : function(request, data) {
// call the overriden method - it will put the data that I
// want into request.xmlData
this.callParent(arguments);
// copy the data in request.xmlData. In this case the XML
// data will always be in the parameter called 'XML'
Ext.apply(request.params, {
XML: request.xmlData
});
// Already copied the request payload and will not send it,
// so we delete it from the request
delete request.xmlData;
// return the modified request object
return request;
}
});
Ext.define("MyApp.model.MyModel", {
extend : "Ext.data.Model",
requires : [
'MyApp.utils.data.writer.XmlInAPostParameter'
],
fields : [ 'field_A', 'field_B' ],
proxy : {
type : 'ajax',
api : {
read : '/mymodel/read.whatever',
update : '/mymodel/write.whatever'
},
reader : {
type : 'xml'
},
writer : {
// use the alias we registered before
type : 'xml_in_a_post_parameter'
}
}
});

extjs jsonstore post params

i'm very new to extjs and i'm trying to make some sense of from what i know from Jquery. I want to have an object to be used application wide as key=>val. I think that using a store is the way to go about it but i can't get it to post any parameters. I have tried dozens of variations to call it but no luck. The code i'm using for now is
var store = new Ext.data.JsonStore({
proxy: new Ext.data.HttpProxy({
method: 'POST' ,
url: '/LoadLanguage.html',
}),
autoload: true,
baseParams: {
'code' : code
},
root: '',
fields: [{name: 'Time', mapping: 'Time', type: 'int'}]
});
Problem is that the $_POST variable is always empty and the GET is like http://lordos.home.local/LoadLanguage.html?_dc=1305874986764&page=1&start=0&limit=25
I need it to post the parameters cause GET will not do.
Thanx
I'm trying to understand what you're doing to please forgive me if this is just not going to work for you.
If you want to have a key=>val storage mechenisim I would suggest the KISS method and use a literal JS object to store / get the data.
// Define a namespace.
window.MyNamespace = {};
// Add my config object to hold key => balue
MyNamespace.config = {};
MyNamespace.config = {
key : 'value',
key2 : 'value2'
};
Do do an ajax request I would use...
Ext.Ajax.Request({
method:'POST', // This is the default value, here for you to see.
url:'/LoadLanguage.html',
params: {
'post_key1' : 'post_value1',
'post_key2' : 'post_value2'
},
success:function(response) {
var text = response.responseText;
MyNamespace.config.language = text;
}
});

Resources