I'm working on a basic Sencha Touch application that displays a list of text messages and the name of an associated user that sent the message. I have followed the tutorials online on how to setup model associations but each tutorial assumes that the server produces data with a nested structure.
The data I am working with has a flat structure with primary/foreign key relationships, and I cannot figure out how to get Sencha to load both stores from a single response.
model/User.js
Ext.define('App.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'uid', type: 'number' },
{ name: 'name', type: 'string' },
]
}
});
store/Users.js
Ext.define('App.store.Users', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.User',
autoLoad: true,
}
});
model/Message.js
Ext.define('App.model.Message', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'number' },
{ name: 'uid', type: 'number' },
{ name: 'message', type: 'string' }
],
associations: [{
type: 'belongsTo',
model: 'App.model.User',
primaryKey: 'uid',
foreignKey: 'uid'
}],
proxy: {
type: 'jsonp',
url: 'messages.json',
reader: {
type: 'json',
rootProperty: 'req_messages'
}
}
}
});
store/Messages.js
Ext.define('App.store.Messages', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.Message',
autoLoad: true,
}
});
The messages are correctly loaded and displayed by my application (sample JSON response below), but I cannot figure out how to get the associated users to be loaded into the store. Can this be solved with a configuration, or will I need a custom reader? Any help appreciated!
Sample JSON
{
"users": [{
"uid": "1",
"name": "John"
}, {
"uid": "3033",
"name": "Noah"
}],
"req_messages": [{
"id": "539",
"uid": "1",
"message": "my message"
}, {
"id": "538",
"uid": "1",
"message": "whoops"
}, {
"id": "534",
"uid": "3033",
"message": "I love pandas."
}]
}
I've never really worked with associations and I went through the document to try to find something that would load two stores with on request, but I couldn't find anything. So here's how I would do it :
Model
Ext.define('App.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
'uid',
'name'
]
}
});
Ext.define('App.model.Message', {
extend: 'Ext.data.Model',
config: {
fields: [
'id',
'message',
'uid'
],
associations: { type: 'hasOne', model: 'User', primaryKey: 'uid', foreignKey: 'uid'}
}
});
Stores
Ext.define('App.store.Users', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'http://www.titouanvanbelle.fr/test.json',
reader: {
type: 'json',
rootProperty: 'users'
}
},
listeners:{
load:function(s,r,success,op){
var msgs = JSON.parse(op.getResponse().responseText).req_messages;
Ext.each(msgs, function(msg) {
Ext.getStore('Messages').add(Ext.create('App.model.Message',msg));
});
}
}
}
});
Ext.define('App.store.Messages', {
extend: 'Ext.data.Store',
config: {
model: 'App.model.Message'
}
});
List
Ext.define("App.view.Main", {
extend: 'Ext.Panel',
config: {
fullscreen: true,
layout:'fit',
items: [{
xtype:'list',
store:'Messages',
itemTpl: new Ext.XTemplate(
'<tpl for=".">',
'{[this.getUserName(values)]} : {message}',
'</tpl>',
{
getUserName(v){
var s = Ext.getStore('Users'),
u = s.getAt(s.find('uid',v.uid));
return u.get('name');
}
}
)
}]
}
});
And you'd get something like this :
Hope this helps. If you need explanation, let me know.
Related
How to load localstorage data in list view in sencha touch?
I have my model:
Ext.define('SenchaWebWorker.model.tweetsModel', {
extend: 'Ext.data.Model',
requires:['Ext.data.proxy.LocalStorage'],
config: {
fields: [
{ name: 'id', type: 'string' },
{ name: 'text', type: 'string' },
{ name: 'date', type: 'string' },
{ name: 'uname', type: 'string' },
{ name: 'uid', type: 'string' },
{ name: 'uimgurl', type: 'string' }
],
proxy: {
type: 'localstorage',
id : '_tweetStore'
}
}});
and my store:
Ext.define('SenchaWebWorker.store.tweetStore', {
extend: "Ext.data.Store",
config: {
storeId: '_tweetStore',
model: 'SenchaWebWorker.model.tweetsModel',
autoLoad:true
}});
please give me some example if possibel.
Thanks.
It's very easy to do, just simply reference your store in the config object of your list, i.e:
Ext.define('MyApp.view.MyList', {
extend: 'Ext.dataview.List',
xtype: 'MyList',
config: {
store : 'MyStore',
itemTpl : document.getElementById('tpl_my_list').innerHTML
}
});
All you need to do is set store property of list to _tweetStore
Ext.define('SenchaWebWorker.view.tweetsList', {
extend: 'Ext.List',
xtype: 'tweetlist',
config: {
store:'_tweetStore',
scrollable:true,
scrollToTopOnRefresh:true,
deselectOnContainerClick:true,
............
............
}
});
Since you have autoLoad set to true, no need to explicitly load store data.
I am using Ext.plugin.PullRefresh plugin which is working fine when I directly run my app on
the browser but when I build my production through sencha cmd 4.0 its duplicating my content whenever I pull to refesh.
I have already used idProperty on my model.
My Jsonp:
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:
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', {
extend:'Ext.Panel',
xtype:'ViewCommentDetail',
requires:['Ext.plugin.PullRefresh'],
extend:'Ext.Panel',
config:{
layout:'vbox',
items:
[{
xtype:'appbar',
},{
flex:1,
xtype:'list',
store:'Comments',
plugins: [
{
xclass: 'Ext.plugin.PullRefresh',
pullRefreshText: 'Pull down for new Comments',
}
],
disableSelection :true,
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>',
}]
}
});
Have you added a requires for it? that is
requires:['Ext.plugin.PullRefresh']
or something like that?
I have also faced this type of duplicating record issue, In my case i have put an autogenerated id field in my json, like this way
{
"items": [
{
"id": 0,
"ContactName": "Aanitha Ps",
},
{
"id": 1,
"ContactName": "Aby",
}
]
}
and reference that id field in my model, i think sencha some times not taking model default id field.
Ext.List does not fill with the data of store, only shows two lines of empty list item. When I debug with firebug, I saw store is filled with the information in json data but list items does not shown.
Store object
Ext.define('MyApp.store.ListStore', {
extend: 'Ext.data.Store',
autoLoad: true,
config:
{
model: 'MyApp.model.NewsData',
fields: [{ name: 'haberId', mapping: 'haberId' },
{ name: 'haberGonderen', mapping: 'haberGonderen' },
{ name: 'haberDetay', mapping: 'haberDetay' },
{ name: 'haberZaman', mapping: 'haberZaman'}]
},
proxy: {
id: 'ListStore',
access: 'public'
}});
News object
Ext.define('MyApp.model.NewsData', {
extend: "Ext.data.Model",
config: {
fields: [
'haberId',
'haberGonderen',
'haberDetay',
'haberZaman'
]
}});
List View
Ext.define('MyApp.view.ListTemplate', {
extend: 'Ext.List',
title: 'Haber Listesi',
store : 'ListStore',
fullscreen: true,
itemTpl : '{haberGonderen}'});
Anybody has any idea?
Try this. May be this helps you.
Store.js
Ext.define('MyApp.store.ListStore', {
extend: 'Ext.data.Store',
config:
{
autoLoad: true,
model: 'MyApp.model.NewsData',
proxy: {
id: 'ListStore',
access: 'public'
},
fields: [{ name: 'haberId', mapping: 'haberId' },
{ name: 'haberGonderen', mapping: 'haberGonderen' },
{ name: 'haberDetay', mapping: 'haberDetay' },
{ name: 'haberZaman', mapping: 'haberZaman'}]
}
});
ListTemplate.js
Ext.define('MyApp.view.ListTemplate', {
extend: 'Ext.List',
config: {
fullscreen: true,
title: 'Haber Listesi',
store : 'ListStore',
itemTpl : '{haberGonderen}'
}
});
I am trying to get some master data from server in JSON format and bind it to selectfield with the help of Store.
Find my code below
Model
Ext.define('Mobile.model.OrganizationModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'Name', type: 'string' },
{ name: 'Id', type: 'int' }
]
}
});
Store
Ext.define('Mobile.store.OrganizationStore', {
extend: 'Ext.data.Store',
model: 'Mobile.model.OrganizationModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'login/GetOrgList',
method: 'GET',
reader: {
type: 'json'
}
}
});
View
Ext.define("Mobile.view.LoginView", {
extend: "Ext.form.FormPanel",
alias: "widget.login",
id: 'loginFormPanel',
config: {
margin: '0 auto',
name: 'loginform',
frame: true,
url: 'login/Authenticate',
title: 'something',
items: [
{
xtype: 'fieldset',
itemId: 'LoginFieldset',
margin: '10 auto 0 auto ',
title: '',
items: [
{
xtype: 'selectfield',
label: 'Organization',
name: 'Organization',
store: 'OrganizationStore',
displayField: 'Name',
valueField: 'Id',
placeHolder: 'Select a Value'
}
]
},
]
}
});
APP.js
Ext.application({
name: "Mobile",
controllers: ["LoginController"],
views: ['LoginView', 'HomeView'],
models: ['UserModel', 'OrganizationModel'],
stores: ['OrganizationStore'],
launch: function () {
var loginPanel = Ext.create('Ext.Panel', {
layout: 'fit',
items: [
{
xtype: 'login'
}
]
});
Ext.Viewport.add(loginPanel);
}
});
JSON Data format is
[{"Id":1,"Name":"Company 1"},{"Id":2,"Name":"Company 2"},{"Id":3,"Name":"Company 3"}]
The problem is it is not sending request to server and loading JSON data and binds. Any idea about this issue?
update you store code to
Ext.define('Mobile.store.OrganizationStore', {
extend: 'Ext.data.Store',
config:{
model: 'Mobile.model.OrganizationModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'login/GetOrgList',
method: 'GET',
reader: {
type: 'json'
}
}
}
});
I want to make a simple request like Ext.Ajax.request and display it in a list. But it does not work.
I have a URL like this
http://server/GetContacts.aspx?CustAccount=10019
Can someone tell me exactly how it works and what I should consider?
This is an example of what I get back.
{
"HasError": false,
"ErrorString": "",
"Data": [
{"ContactPersonId":"","Name":"","FirstName":"","MiddleName":"","LastName":"","Phone":"","CellularPhone":"","Telefax":"","Email":"","Url":"","Address":"","ZipCode":"","City":"","Street":"","Country":"","Function":""}
]
}
Ext.regModel('kunden', {
idProperty: 'id',
fields: [
{ name: 'ContactPersonId', type: 'string' },
.
.
.
{ name: 'Function', type: 'string' }
]
});
Ext.regStore('kundenStore', {
model: 'kunden',
sorters: [{
property: 'LastName'
}],
proxy: {
type: 'ajax',
url: 'http://server/GetContacts.aspx?CustAccount=10019'
},
reader: {
type: 'json',
root: 'Data'
}
});
NotesApp.views.kundenList = new Ext.List({
id: 'kundenList',
store: 'kundenStore',
grouped: true,
indexBar : true,
itemTpl: '<div class="list-item-title">{firstname} {lastname}</div>' +'<div class="list-item-narrative">{email}</div>',
listeners: {}
}
});
It can be so easily XP