I need help with my xtemplate and store with proxy. No matter what I am trying, I am stuck in this problem. The xtemplate is only showing data from a store without using a proxy.
Working store:
Ext.create('Ext.data.Store', {
storeId : 'viewStore',
model : 'dataview_model',
data : [
{statistic: '213213', description: 'Hallo'},
{statistic: '534345', description: 'Alloh'},
]
});
Working Xtemplate and data config
xtype: 'component',
cls: 'kpi-tiles',
id: 'statisticsBoxes',
height: 100,
tpl: [
'<div class="kpi-meta">',
'<tpl for=".">',
'<span>',
'<div class="statsDiv">{statistic}</div> {description}',
'</span>',
'</tpl>',
'</div>'
],
data: [{
description: Ext.getStore('statisticsStore').getAt(0).data.statistic,
statistic: Ext.getStore('viewStore').getAt(0).data.statistic
},{
description: Ext.getStore('viewStore').getAt(1).data.description,
statistic: Ext.getStore('viewStore').getAt(1).data.statistic
}],
But when I am changing the data for the template so it will load data from the Statistics store, the following error occurs in the console.log: Uncaught TypeError: Cannot read property 'getAt' of undefined.
Data config:
data: [{
description: 'the description',
statistic: Ext.getStore('statisticsStore').getAt(0).data.statistic
}],
Statistics store:
Ext.define('ExecDashboard.store.Statistics', {
extend: 'Ext.data.Store',
alias: 'store.statistics',
storeId: 'statisticsStore',
model: 'ExecDashboard.model.Statistics',
proxy: {
type: 'ajax',
url: '/statistics',
reader: 'json'
}
});
Produces the following JSON:
[{"statistic":"1"}, {"statistic":"2"}]
The store is loaded in the viewModel:
stores: {
Statistics: {
type: 'statistics',
autoLoad: true
}
}
I think the problem is that the store is not loaded at that moment. But I don't know how to solve this problem. I know that 'Ext.getStore('statisticsStore').getAt(0).data.statistic' works in the console.log when the store is loaded.
Use an Ext.view.View, that's exactly what the class is for:
xtype: 'dataview',
cls: 'kpi-tiles kpi-meta',
id: 'statisticsBoxes',
height: 100,
itemSelector: '.statsDiv',
tpl: [
'<tpl for=".">',
'<span>',
'<div class="statsDiv">{statistic}</div> {description}',
'</span>'
'</tpl>'
],
store: 'statisticsStore'
You probably need to set autoLoad: true on your store.
An event listener on the store in my viewModel solves the problem.
Statistics: {
type: 'statistics',
autoLoad: true,
listeners: {
load: function(){
var data = [{"description": "New", "statistic" : this.data.items[0].data.statistic}];
Ext.getCmp('statisticsBoxes').update(data);
}
}
}
When the store is loaded, the event will be fired which updates the Xtemplate with new data
Related
I'm just trying to parse a nested JSON in a Model that I've created. I've created three models (Detalhe, Propriedade and Assinatura) for each JSON node. The store proxy isn't parsing the data for Detalhe's model.
I also tryed to put the "mapping" property on hasMany attribute, with the same name of a node. It didn't work. Ext.Template also can't read store data and fill the Viewer.
Any suggestions?
Here is my JSON:
{
"details": {
"customProperties": [
{
"chave": "Data de Criação",
"valor": "30/10/2013"
},
{
"chave": "Nome",
"valor": "Blah Stuff"
}
],
"signatures": [
{
"nome": "Data de Criação",
"data": "30/10/2013"
},
{
"nome": "Nome do Cliente",
"data": "John Doe"
}
]
},
"success": true
}
And the parsing code:
Ext.define('Propriedade', {
extend: 'Ext.data.Model',
fields: ['chave', 'valor'],
belongsTo: 'Detalhe'
});
Ext.define('Assinatura', {
extend: 'Ext.data.Model',
fields: ['nome', 'data'],
belongsTo: 'Detalhe'
});
Ext.define('Detalhe', {
extend: 'Ext.data.Model',
hasMany: [
{model: 'Propriedade', name: 'customProperties'},
{model: 'Assinatura', name: 'signatures'}
]
});
var store = Ext.create('Ext.data.Store', {
id: 'customPropertiesStore',
model: 'Detalhe',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'info.json',
reader: {
type: 'json',
root: 'details',
successProperty: 'success'
}
}
});
var docId = "some id";
var folders = "some folder";
store.load({
params: {docId: docId, folders: folders}
});
var tpl = new Ext.XTemplate(
'<tpl for="customProperties">',
'<div class="customPropertyItem">',
'<span><label>{chave}</label>: {valor}</span>',
'</div>',
'</tpl>',
'<tpl for="signatures">',
'<div class="signatureItem">',
'<span><label>{nome}</label>: {data}</span>',
'</div>',
'</tpl>'
);
var viewer = Ext.create('Ext.view.View', {
store: Ext.data.StoreManager.lookup('customPropertiesStore'),
tpl: tpl,
itemSelector: 'customPropertyItem',
emptyText: 'Nothing found.'
});
I've got a Json file......
[
{
"Title":"Package1",
"id":"1",
"POI":[
{
"Title":"POI1",
"LayerID":"1",
},
{
"Title":"POI2",
"LayerID":"1",
}
},
{
"Title":"Package2",
"id":"2",
"POI":[
{
"Title":"POI3",
"LayerID":"2",
},
{
"Title":"POI4",
"LayerID":"2",
}
}
]
populating a store.....
Ext.define('Murmuration.store.MyPackages', {
extend: 'Ext.data.Store',
xtype: 'myPackages',
config: {
model: 'Murmuration.model.PackagesModel',
proxy: {
type: 'ajax',
url : 'data/store.json',
reader: {
type: 'json'
}
},
autoLoad: true
}
});
with a model......
Ext.define('Murmuration.model.PackagesModel', {
extend: 'Ext.data.Model',
xtype: 'packagesModel',
config: {
fields: [
{name: 'Title', type: 'string'},
{name: 'id', type: 'int'}
]
}
});
for said list......
Ext.define('Murmuration.view.homeList', {
extend: 'Ext.List',
xtype: 'homeList',
fulscreen: true,
config: {
title:'Murmuration',
itemTpl: '<div>{Title}</div>',
store:'MyPackages',
fulscreen: true,
}
});
The list Items are successfully being populated with 'Package1' and 'Package2'. But for the life of me I can't successfully change the code to populate the list with the POI titles for the fist package........'POI1' and 'POI2'. How would I go about successfully implementing the following? Any help would be greatly appreciated.
The json you've given is nested so things little different here. First thing is, you need to specify a rootProperty in your reader. So you define a root element in your json and that element will be set to rootProperty.
Next part is, you have POI as array of objects. So you'd need a separate model for POI.
Model for POI can be defined -
Ext.define('Murmuration.model.POIModel',{
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'Title', type: 'string'},
{name: 'LayerID', type: 'int'}
],
belongsTo:'Murmuration.model.PackagesModel'
}
});
After a close look, you'll notice there's one extra config belongsTo. This represents many to one association with your PackageModel since there are many POI in each package.
After doing this, you'd need to change you PackageModel also to -
Ext.define('Murmuration.model.PackagesModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'Title', type: 'string'},
{name: 'id', type: 'int'}
]
},
hasMany:{
associationKey:'POI',
model:'Murmuration.model.POIModel',
name:'POI'
}
});
here, hasMany represents that this model is having multiple model instances of POI model. associationKey is the key POI from you json and model gives the model instance of POI model.
After doing that you'd need to change your reader in store to -
Ext.define('Murmuration.store.MyPackages', {
extend: 'Ext.data.Store',
config: {
model: 'Murmuration.model.PackagesModel',
proxy: {
type: 'ajax',
url : 'data/store.json',
reader: {
type: 'json',
rootProperty:'items'
}
},
autoLoad: true
}
});
rootProperty should be set to root of you json. I assumed it could be items here.
Finally in you view you can have template set up like this -
itemTpl: new Ext.XTemplate(['<div>Package Title => {Title}'+
'<tpl for="POI"><h6>POI title => {Title}</h6><h6>POI layer => {LayerID}</h6></tpl></div>'
]),
2 things I found in your code are not correct though -
Store and Model can not have a xtype.
All the config options should be inside config:{} only.
This topic has been discussed several times on the web but all subjects none helped me solve my problem.
My javascript code receives the JSON nested data. All JSON data Level 1 data are transcribed in the grid panel but all child data none.
I have tried so many ways but impossible.
That's why I'm asking you to help me please.
My JSON:
{
"success":true,
"error":false,
"redirectUrl":null,
"fund":[{
"cat_id":1,
"catname":"Europe OE Japan Large-Cap Equity",
"region":{
"region_id":2,
"region_name":"JAPAN"
}
},{
"cat_id":2,
"catname":"Europe OE Europe Large-Cap Growth Equity",
"region":{
"region_id":1,
"region_name":"EUROPE"
}
}]
}
MY model:
var Recommended = new function() {
this.DataModel = function() {
Ext.define('Fund', {
extend: 'Ext.data.Model',
fields: [{
name: 'catname',
type: 'string'
},{
name: 'cat_id',
type: 'int'
}],
proxy :{
type: 'rest',
url: application +'directory/function',
reader: {
type: 'json',
root: 'fund'
}
},
associations: [{
type: 'hasOne',
model: 'Region',
primaryKey: 'region_id',
name:'region'
}]
});
Ext.define('Region', {
extend: 'Ext.data.Model',
fields: [{
name: 'region_name',
type: 'string'
},{
name: 'region_id',
type: 'int'
}]
});
}
My Store & grid Panel:
this.JSONstore = function() {
var storeRecommended;
storeRecommended = Ext.create('Ext.data.Store', {
model: 'Fund',
autoLoad:true,
groupField: 'region_name'
});
var colModel =
[
{
text: 'REGION',
width: 200,
dataIndex: 'region_name',
name:'region_name',
mapping:'region.region_name'
},{
text: 'MORNINGSTAR',
width: 300,
dataIndex: 'catname',
name:'catname'
}
];
var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{
groupHeaderTpl: 'Classe: {name} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})',
hideGroupedHeader: false
});
var grid = Ext.create('Ext.grid.Panel', {
renderTo: 'recommendedlists',
collapsible: true,
iconCls: 'icon-grid',
frame: true,
store: storeRecommended,
width: 1200,
height: 400,
title: 'Test',
resizable: true,
features: [groupingFeature],
columns: colModel,
fbar : ['->', {
text:'Clear Grouping',
iconCls: 'icon-clear-group',
handler : function(){
groupingFeature.disable();
}
}]
});
}
this.initControlsOnload = function() {
Recommended.DataModel();
Recommended.JSONstore();
}
} // close Recommended function
The problem is your store bound to the grid knows nothing about Regions. It stores Funds. So you can't ask for a column to map to a data property that's not in the store.
The store is flat list of Fund records. And sure an individual Fund itself might know about the Region it belongs to, but the store containing a list of funds does not.
What to do?
What needs to happen is flattening out of your data structure on the client side. Why? Because the grid is flat. If you had multiple regions per fund - then we would be talking about a different solution.
How to do that?
If you control the server side of this app then add a Region field to the Fund object, then your data set is simple, straight forward and more importantly flat. If you can't (or don't want to) change the server side, then you can change the client side Model mapping. Essentially you would change your Fund model to something like this:
Ext.define('Fund', {
extend: 'Ext.data.Model',
fields: [
{ name: 'catname', type: 'string' },
{ name: 'cat_id', type: 'int' },
{ name: 'region_name', type: 'string',
mapping: 'region.region_name'},
{ name: 'region_id', type: 'int',
mapping: 'region.region_id'}
]
....
});
You see what we did there? We flattened the Region data into the Fund record. And now your store will have no problems accessing Region name data by name.
Good Luck,
Dmitry.
I have following sample application, where i am trying to implement paging functionality for sencha touch , but i am facing issues in setting the page size and when i hit load more same old data is being repeated in the list, please can i know where i am going wrong ?
Ext.define("WEB.view.SearchView", {
extend: 'Ext.dataview.List',
xtype: 'SearchView',
requires: [
'Ext.dataview.List',
'Ext.data.Store',
'Ext.List'
],
config: {
title: 'Search Results',
plugins: [
{
xclass: 'Ext.plugin.ListPaging',
autoPaging: false,
loadMoreText: 'Loading...',
noMoreRecordsText: 'No More Records'
},
{ xclass: 'Ext.plugin.PullRefresh' }
],
//onItemDisclosure: false,
store: {
id: 'MySearchStore',
autoLoad:false,
pageSize: 15,
clearOnPageLoad: false,
fields: [
{ name: "ShortDescription", type: "string" },
{ name: "MatchId", type: "bool" }
],
proxy: {
type: 'jsonp',
url: 'http://Example.com',
reader: {
type: 'json',
rootProperty: 'd'
}
}
},
itemTpl: new Ext.XTemplate('<tpl if="MatchId == 1">', '<p style="color: #ff9900">{BlockNo}</p><p>{ShortDescription}</p>', '</tpl>',
'<tpl if="MatchId == 0">', '<p >{BlockNo}</p><p>{ShortDescription}</p>', '</tpl>'
)
}
});
This is a simple issue but can be a bottleneck when you are starting out...
Set the pageParam in the store to what you use for pagination on the server side... Then everything should work fine...
Note: Your actual pagination logic should be on the server side... Sencha only provides a means to display the content a few at a time...
Ext.define('MyApp.store.MyJsonStore', {
extend: 'Ext.data.Store',
config: {
storeId: 'MyJsonStore',
proxy: {
type: 'ajax',
pageParam: 'page',//This parameter needs to be modified
reader: {
type: 'json'
}
}
}
});
After URL has been reached, how to show this data to grid, autoLoad:true, only loads firstly defined URL, but how to "dynamically" show loaded JSON to grid?, Reload the data with newly called JSON?
buttons: [{
text: 'Load1',
handler:function(){
myStore.getProxy().url = 'app/kontaktGrid1.json';
myStore.load();
grid.getView().refresh();
}},{
text: 'Load2',
handler:function(){
myStore.getProxy().url = 'app/kontaktGrid2.json';
myStore.load();
grid.getView().refresh();
}}]
Ext.define('app.gridStore', {
extend: 'Ext.data.Model',
fields: [
'name', 'email', 'phone'
]
});
var myStore =Ext.create('Ext.data.Store', {
model: 'app.gridStore',
proxy: {
type: 'ajax',
url : '',
reader:{
type:'json'
}
},
autoLoad:false
});
--Grid in Border Layout Center--
items:[{
xtype:"grid",
id:"kontaktGrid",
store: myStore,
border: false,
columns: [
{header: 'name',sortable : false, dataIndex: 'name'},
{header: 'email',sortable : false, dataIndex: 'email'},
{header: 'phone',sortable : false, dataIndex: 'phone'}
]
}]
This isn't working, only loading from server no dispalying data.
first, why did you load your json like that ? even it's working... this is the simple way :
text: 'Load1',
handler:function(){
myStore.load({
scope : this,
url : 'app/kontaktGrid1.json'
});
//myStore.getProxy().url = 'app/kontaktGrid1.json';
//myStore.load();
//grid.getView().refresh();
}
from docs, the definition of method load is
Loads data into the Store via the configured proxy..
second, your probem is only loading from server no dispalying data..
it's mean no error with json, store, and the model...
i think your problem is in the grid panel..
try show us how did you create the grid
make sure your grid column is refer(dataIndex) to your json
var grid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [
{text : 'name', sortable : false, dataIndex:"name"},
{text : 'email', sortable : false, dataIndex:"email"},
{text : 'phone', sortable : false, dataIndex:"phone"}
],
//.....