I am new to ExtJS so please excuse if this is very basic. I googled but couldn't find any useful answer.
I have a Store with proxy type AJAX:
tableStore = Ext.create('Ext.data.Store', {
model: 'TableData',
pageSize: 20,
proxy: {
type: 'ajax',
url: url
}
});
The call to url returns a JSON object. I want to get this JSON object in some local variable to do some processing.
Is this possible?
Thanks.
You can refer to the data obtained in the method transform:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'}
, {name: 'title', type: 'string'}
]
, proxy: {
type: 'rest'
, reader: {
type: 'json'
, transform: {
fn: function (data) {
//you code here
return data;
}
, scope: this
}
}
}});
try with this
tableStore.getProxy().getReader().rawData
Related
I have a simple model, let's say:
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'}
]
});
And a json file that looks like this:
{
"DatabaseInJSON": {
"Users": [
{
"KeyFirstName": "John",
"KeyLastName": "Doe"
},{
"KeyFirstName": "James",
"KeyLastName": "Howlett"
}
],
"OtherStuffWeDontCareAbout": [
...
]
}
}
My question is:
If I create a store like this, how can i map the attribute "firstname" from my model to "KeyFirstName" from my json ?
Ext.define('my.custom.Store', {
extend: 'Ext.data.Store',
model: 'UserModel',
proxy: {
type: 'ajax',
url: 'path/to/my/file.json',
reader: {
type: 'json',
rootProperty: 'DatabaseInJSON'
}
}
});
You need to either employ mapping or a convert function
Have a look at the demo here which demonstrates both in action.
For the sake of the demo I turned your store into a memory proxy store and you are I presume also accessing your rootProperty wrong as it should be rootProperty: 'DatabaseInJSON.Users'
Code:
Ext.application({
name: 'Fiddle',
launch: function() {
myData = {
"DatabaseInJSON": {
"Users": [{
"KeyFirstName": "John",
"KeyLastName": "Doe"
}, {
"KeyFirstName": "James",
"KeyLastName": "Howlett"
}],
"OtherStuffWeDontCareAbout": {}
}
};
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'firstname',
mapping: 'KeyFirstName',
type: 'string'
}, {
name: 'lastname',
convert: function(v, record) {
return record.data.KeyLastName;
},
type: 'string'
}]
});
Ext.define('my.custom.Store', {
extend: 'Ext.data.Store',
model: 'UserModel',
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'DatabaseInJSON.Users'
}
}
});
myStore = Ext.create('my.custom.Store', {
data: myData
});
console.log(myStore.getRange());
}
});
Generally your Json properties should match the same names of your fields so that the reader can read them properly, to map 'KeyFirstName' to 'firstname' I think your best option would be to create a mapping in the field definition on the model.
This would apply this globally for all requests and I believe it would reverse the mapping when it come to saving the data.
To use the mapping in your case, you would need something like:
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string', mapping: function(data) { return data.KeyFirstName; } },
{name: 'lastname', type: 'string', mapping: function(data) { return data.KeyLastName; } }
]
});
Other than changing the format of the JSON data, the only other way I can think of would be to override the read or getResponseData method of the JsonReader
My problem is the json I am getting doesn't have a root. I can get the store to load the URL and I get the JSON back but the store data is empty and nothing shows in the callback.
Json:
[
{
"symbol": "GM"
},
{
"symbol": "GA"
}
]
Model and Store:
Ext.define('Symbol', {
extend: 'Ext.data.Model',
fields: ['symbol']
});
Ext.define('Doc.store.symbol', {
extend: 'Ext.data.Store',
model: 'Symbol',
proxy: {
type: 'jsonp',
url: 'datasource/symbol',
reader: {
type: 'json',
model: 'symbol'
},
}
});
I tried removing the root as well but nothing came back in the store or the callback. My googlefu is turning up nothing good on json without root.
the root should be defined as blank root:''
Here is a code demonstrating the proper setup:
Ext.define('boomer', {
extend:'Ext.data.Model',
fields: ['symbol'],
proxy: {
type: "ajax",
url: "data.json",
extraParams: {
},
reader: {
type: "json",
root: "",
successProperty: "success"
}
}
});
var store = Ext.create('Ext.data.Store',{
model: 'boomer',
});
store.load({
callback:function(){
Ext.Msg.alert('Store Items', store.data.items.length);
console.log(store.data.items);
}
});
Here is a fiddle demonstrating working code.
extend Ext.data.reader.Json to adjust your response.Later use it inside proxy reader.
there is a answer here
var RouteSeqStore = Ext.create('Ext.data.JsonStore', {
model: 'RouteSeqModel',
storeId: 'RouteSeqStore',
autoLoad: false,
sorters: [{
property: 'Route_Seq',
direction: 'ASC'
}],
proxy: {
type: 'ajax',
url: 'route/get-routeseq.php',
api: {
destroy: 'route/delete-routeseq.php',
create: 'route/insert-routeseq.php',
//read: 'http://visual04/ModuleGestion/php/Pays.php?action=read',
update: 'route/update-routeseq.php',
},
actionMethods: 'POST',
baseParams: {
_id : 0,
},
reader: {
type: 'json',
idProperty: '_id'
},
writer: {
type: 'json',
id: '_id'
}
}
});
this is my EXTJS post json code, when posting 1 object, extjs wont have square bracket
{"_id":11,"Route_Seq":1,"Location_Name":"B.STATION","Route_LocationID":"1","Route_ID":"2","id":null}
when multi array json result will having the [ ] bracket, how to let JSON post with square bracket even 1 object only
what i expect the result is :
[{"_id":11,"Route_Seq":1,"Location_Name":"B.STATION","Route_LocationID":"1","Route_ID":"2","id":null}]
any solution?
Simple: just set the allowSingle config on your writer to be "false". This will force the writer to send model instances as an array ALWAYS, regardless of the number being persisted in any given request. Be sure to check out the docs for this.
Here is my model:
Ext.define('DynTabBar.model.Menu',{
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'Title', type: 'string'
}, {
name: 'Level', type: 'int'
}, {
name: 'Parent', type: 'string'
}]
}
});
Store:
Ext.define('DynTabBar.store.MenuItems', {
extend: 'Ext.data.Store',
xtype: 'menustore',
config: {
storeId: 'menuStore',
model: 'DynTabBar.model.Menu',
autoLoad: false,
proxy: {
type: 'ajax',
id: 'menuproxy',
url: 'http://localhost:50567/api/Menu',
reader: {
type: 'json'
}
}
}
});
In controller I have smth like that:
var mainStore = Ext.getStore('menuStore');
mainStore.load();
My json respone from server is:
[{"Title":"home","Level":1,"Parent":""},{"Title":"home1","Level":2,"Parent":"home"},{"Title":"home2","Level":2,"Parent":"home"},{"Title":"info","Level":1,"Parent":""},{"Title":"info1","Level":2,"Parent":"info"},{"Title":"info2","Level":2,"Parent":"info"},{"Title":"info3","Level":2,"Parent":"info"}]
But store data is empty. What I'm missing or doing wrong?
I fixed the problem, the problem is that I'm not waiting while store data is loaded and do something while store isn't loaded. I fix that doing what I need in store loaded callback.
mainStore.load(callback);
I've been trying to figure this out all evening but to no avail. I have a JSON structure as follows (coming from another system so I can't change its structure):
{
"parents":{
"parent":[
{
"parentId":1,
"children":{
"child":[
{
"childId":1,
},
{
"childId":2,
}
]
}
},
{
"parentId":2,
"children":{
"child":[
{
"childId":1,
},
{
"childId":2,
}
]
}
}
],
"pageNum":1,
"pageSize":2
}
}
However, I can't figure out what the correct structure for the data models should be. I've tried the following but it does not work. BTW, I can access the parent information. The issue is with accessing the child information. So, I guess there is something wrong with how I've set up the relationship data.
Ext.regModel("ParentModel", {
hasMany: {
model: 'ChildrenModel',
name: 'children.child' // not too sure about this bit
},
fields: [
{name: 'parentId', type: 'string'}
],
proxy: {
type: 'ajax',
url : 'models.json',
reader: {
type: 'json',
root: 'parents.parent' // this works fine
}
}
});
Ext.regModel('ChildrenModel', {
belongsTo: 'ParentModel', // not too sure about this bit
fields: [{name: 'childId', type: 'string'}]
});
with a data store:
Ext.regStore('ParentModelStore', {
model: 'ParentModel',
autoLoad:true
});
I'm using the following template which gets me the parent information, but I can't get the child data from it:
myapp.views.ParentView = Ext.extend(Ext.Panel, {
layout: 'card',
initComponent: function() {
this.list = new Ext.List({
itemTpl: new Ext.XTemplate(
'<tpl for=".">',
'<div>',
'{parentId}', // this works fine
'</div>',
'<tpl for="children.child">', // this doesn't work
{childId}
'</tpl>',
'</tpl>',
),
store: 'ParentStore',
});
this.listpanel = new Ext.Panel({
layout: 'fit',
items: this.list,
});
this.items = this.listpanel;
myapp.views.ParentView.superclass.initComponent.apply(this, arguments);
},
});
Ext.reg('ParentView', myapp.views.ParentView);
What I'm struggling with is the fact that both the "child" and "parent" elements are surrounded by another element, "children" and "parents" respectively.
Any help much appreciated.
Thanks in advance,
Philip
PS If I remove the outer "children" wrapping element and just leave the inner "child" element (and change "children.child" to "child" in the model definition) the code works fine.
PPS I'm answering my own question:
Doh! I forgot to add the "children" element to the ParentModel's fields.
It should be as follows (note: I didn't need to specify the 'hasMany' or 'associations' elements - not too sure why this is or what is the benefit of including them):
Ext.regModel("ParentModel", {
fields: [
{name: 'parentId', type: 'string'},
{name: 'children'} // VERY IMPORTANT TO ADD THIS FIELD
],
proxy: {
type: 'ajax',
url : 'models.json',
reader: {
type: 'json',
root: 'parents.parent' // this works fine
}
}
});
Ext.regModel('ChildrenModel', {
fields: [{name: 'childId', type: 'string'}]
});
The template works fine too:
'<tpl for="children.child">', // this syntax works too.
{childId}
'</tpl>',
Ran into a similar problem recently..I think.
You need to specify the mapping to the data you want in your model.
For example :
Ext.regModel('Album', {
fields: [
{name: 'artist_name', mapping: 'album.artist.name'},
{name: 'artist_token', mapping: 'album.artist.token'},
{name: 'album_name', mapping: 'album.name'},
{name: 'token', mapping: 'album.token'},
{name: 'small_cover_url', mapping: 'album.covers.s'},
{name: 'large_cover_url', mapping: 'album.covers.l'}
]/*,
getGroupString : function(record) {
return record.get('artist.name')[0];
},*/
});
consumes this JSON:
{
"album":{
"covers":{
"l":"http://media.audiobox.fm/images/albums/V3eQTPoJ/l.jpg?1318110127",
"m":"http://media.audiobox.fm/images/albums/V3eQTPoJ/m.jpg?1318110127",
"s":"http://media.audiobox.fm/images/albums/V3eQTPoJ/s.jpg?1318110127"
},
"artist":{
"name":"New Order",
"token":"OyOZqwkN"
},
"name":"(The Best Of)",
"token":"V3eQTPoJ"
}
},
I've added a converter to allow the template access the data in the model consistently regardless if a single object or an array is returned.
Ext.regModel("ParentModel", {
fields: [
{name: 'parentId', type: 'string'},
{name: 'children', convert:
function(value, record) {
if (value.child) {
if (value.child instanceof Array) {
return value.child;
} else {
return [value.child]; // Convert to an Array
}
}
return value.child;
}
}
],
proxy: {
type: 'ajax',
url : 'models.json',
reader: {
type: 'json',
root: 'parents.parent' // this works fine
}
}
});
Note: I don't actually need to define the ChildrenModel. I guess I can get away without defining it as Sencha must be automatically type converting it.