Hello Everyone,
I am new to EXTJS and want to grasp Extjs models and its complexity as per the json response. For Example I have a sample Json response for which I want to create a model
This is my app.js file
Ext.application({
requires: ['Ext.container.Viewport'],
name: 'AM',
appFolder: 'app',
launch: function() {
console.log('I am in app');
var store = Ext.create('AM.store.ExampleStore');
store.load();
console.log('After Loading the records');
}
});
This is json sample
[
{
"page": "0",
"data": [
{
"firstname": "puneet",
"id": "28170",
"lastname": "srivastava",
"area": "bangalore",
"profession": "Engineer"
},
{
"firstname": "v Durga",
"id": "28171",
"lastname": "Mallikrjuna",
"area": "bangalore",
"profession": "Extjs developer"
}
]
}
]
I created models as per my understanding. Model belongs to data part of json
Ext.define('AM.model.Example', {
extend: 'Ext.data.Model',
fields: ["firstname", "id", "lastname", "area", "profession"],
belongsTo : 'AM.model.Page'
});
Ext.define('AM.model.Page', {
extend: 'Ext.data.Model',
fields: ["page", "data"],
hasMany:{ model:"AM.model.Example", name: "example", associationKey : "data" }
});
Ext.define('AM.store.ExampleStore', {
extend: 'Ext.data.Store',
model : "AM.model.Page",
proxy: {
type: 'ajax',
url: 'example.json',
reader: {
type: 'json',
root: 'spaces'
}
},
listeners : {
'load' : function(store, records, successful) {
console.log('Loading the records');
console.log(store.data);
}
}
})
The data which I am getting after logging the store that contains only {page : 0} and the data part is missing.
Just want to know Where I am making the mistake or Any thing I am not including in the store or models.
Thanks
The Model should be:
Ext.define('AM.model.Example', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string'},
{name: 'id', type: 'int'},
...
});
in your case, root should be data. Root means master node of your Json object.
Ext.define('AM.store.ExampleStore', {
extend: 'Ext.data.Store',
model : "AM.model.Page",
proxy: {
type: 'ajax',
url: 'example.json',
reader: {
type: 'json',
root: 'data'
}
},
listeners : {
'load' : function(store, records, successful) {
console.log('Loading the records');
console.log(store.data);
}
}
})
Related
I am getting some search results back from Elastic in this format
{
"took": 267,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1911,
"max_score": 29.118078,
"hits": [
{
"_index": "myIndex",
"_type": "doc",
"_id": "27c9d14495f7732c6756f0d2688874f",
"_score": 21.179974,
"_source": {
"file": {
"filename": "file1.pdf"
},
"content": "samplecontent"
}
},
{
"_index": "myIndex",
"_type": "doc",
"_id": "27c9d14495f7732c6756f0d2688874f",
"_score": 21.179974,
"_source": {
"file": {
"filename": "file2.pdf"
},
"content": "samplecontent"
}
},
{
"_index": "myIndex",
"_type": "doc",
"_id": "27c9d14495f7732c6756f0d2688874f",
"_score": 21.179974,
"_source": {
"file": {
"filename": "file3.pdf"
},
"content": "samplecontent"
}
}
]
}
}
and would like to display the hits.total (1911) in the header of my grid for example, and hits.hits._source.file.filename and hits.hits._source.content in my grid. I believe I need to setup a hasMany/belongsTo model but am a bit confused by any documentation/examples that I've found as to how to setup that relationship, as well as pick and choose those nested fields to display in the grid. Any help or clarification would be appreciated
My store is defined as
Ext.define('search.store.results', {
extend: 'Ext.data.Store',
alias: 'store.results',
model: 'search.model.hits',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'http://myServer:9200/_search',
reader: {
type: 'json',
rootProperty: 'hits'
}
}
});
And my models are defined as
base
Ext.define('search.model.Base', {
extend: 'Ext.data.Model',
schema: {
namespace: 'search.model'
}
});
hits
Ext.define('search.model.hits', {
extend: 'search.model.Base',
fields: [
{name: 'total', type: 'number'}
],
hasMany:{
model: 'hit',
name: 'hit'
}
});
hit
Ext.define('search.model.hit', {
extend: 'search.model.Base',
fields: [
{name: '_source', type: 'source'}
]
});
source
Ext.define('search.model.source', {
extend: 'search.model.Base',
fields: [
{name: 'file', type: 'file'},
{name: 'content', type: 'string'}
]
});
and file
Ext.define('search.model.file', {
extend: 'search.model.Base',
fields: [
{name: 'filename', type: 'string'}
]
});
however when I load my page I get these errors right off the bat
Uncaught Error: [Ext.createByAlias] Unrecognized alias: data.field.source
and
Uncaught Error: [Ext.createByAlias] Unrecognized alias: data.field.file
UPDATE: This is what the results look like if I change my models to use 'reference' instead of hasMany
Ext.define('search.model.hits', {
extend: 'search.model.Base',
fields: [
{name: 'total', type: 'number'},
{name: 'hits', reference: 'hit'}
]
});
Ext.define('search.model.hit', {
extend: 'search.model.Base',
fields: [
{name: '_source', reference: 'source'}
]
});
Ext.define('search.model.source', {
extend: 'search.model.Base',
fields: [
{name: 'file', reference: 'file'},
{name: 'content', type: 'string'}
]
});
Ext.define('search.model.file', {
extend: 'search.model.Base',
fields: [
{name: 'filename', type: 'string'}
]
});
My store 'load' listener shows this information, broken into separate data structures instead of all being under the 'data' structure where the arrow is (where I'm used to finding my store records)
UPDATE #2:
If I modify my 'hits' model to use hasMany but leave the rest using 'reference' it appears to work as far as grouping my data properly in the records - now I just need to know how to display the nested results in a grid
Ext.define('search.model.hits', {
extend: 'search.model.Base',
fields: [
{name: 'total', type: 'number'}
],
hasMany:{
model: 'hit',
name: 'hit'
}
});
produces
I am using a TreeStore to load data that looks like this:
{
"categories": [{
"text": "Ext JS",
"expanded": "true",
"categories": [{
"text": "app",
"categories": [{
"text": "Application.js",
"categories": "null"
}]
},
{
"text": "button",
"expanded": "true",
"categories": [{
"text": "Button.js",
"categories": "null"
},
{
"text": "Cycle.js",
"categories": "null"
},
{
"text": "Split.js",
"categories": "null"
}]
}
]
}]
}
What I want is to set the leaf property to true or false if the categories property is null or not.
My model looks like this :
Ext.define('TestTree.model.MyModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Boolean'
],
fields: [
{
name: 'text'
},
{
type: 'boolean',
name: 'leaf'
}
]
});
The idea was to use the calculate config of the leaf field for that but if I try to use data.get('categories') I get Field leaf depends on undefined field get and if I try to define the field categories in my model an use data.categories, nothing happens.
I don't know what I am missing!
My store looks like this:
Ext.define('TestTree.store.MyTreeStore', {
extend: 'Ext.data.TreeStore',
requires: [
'TestTree.model.MyModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'MyTreeStore',
autoLoad: true,
model: 'TestTree.model.MyModel',
proxy: {
type: 'ajax',
url: 'resources/data/treeData.json',
reader: {
type: 'json',
rootProperty: 'categories'
}
}
}, cfg)]);
}
});
Thank you!
Create your model with the following init method:
Ext.define("Files", {
extend : "Ext.data.Model",
fields : [{
name: 'categories'
},{
name: 'leaf',
convert : function(value, record) {
return record.get('categories') == 'null';
}
}]
});
This should fix your issue, and here is a fiddle so you can take a look: https://fiddle.sencha.com/#fiddle/gq8
I used calculate instead of convert.
From the doc
Using calculate is the simplest and safest way to define a calculated field.
So the code becomes
Ext.define("Files", {
extend : "Ext.data.Model",
fields : [{
name: 'categories'
},{
name: 'leaf',
calculate : function(data) {
return data.categories === null;
},
depends: ['categories']
}]
});
My json format
Ext.data.JsonP.callback3({"nodes":[
{"node":{"title":"Dane Sample Name - Owner/Stylist/Daymaker","field_headshot":"","body":"Born and raised in Carencro, La., Dane knew from a young age that he wanted to become a successful hairdresser. \n","nothing":""}},
{"node":{"title":"Rahul - Owner/Stylist/Daymaker","field_headshot":"","body":"Since 1995 Jeanne has enjoyed helping people to feel and look beautiful.\n","nothing":""}}]})
Models
Ext.define('SampleApp.model.Drupal', {
extend: 'Ext.data.Model',
uses: [
'SampleApp.model.Drupal2'
],
config: {
fields : [
'node'
],
},
hasMany: {
model: 'Drupal2',
name : 'node',
associationKey: 'node' ,
}
});
Ext.define('SampleApp.model.Drupal2', {
extend: 'Ext.data.Model',
config: {
fields: [
'title','body'
]}
});
Store
Ext.define('SampleApp.store.DrupalStore', {
extend: 'Ext.data.Store',
requires: [
'SampleApp.model.Drupal2'],
config: {
autoLoad : true,
model: 'SampleApp.model.Drupal2',
proxy: {
type: 'jsonp',
url: 'data/data.json',
reader: {
type: 'json',
rootProperty: 'nodes.node'
}
}
}
});
The above is the nested json from drupal view and I am trying to use those 2 models and store to load list in my view.I am trying to add list of titles from node but List is not loading in the view.If I give root property as nodes then it is loading all the data but not mapping to node.Please help me on where I am going wrong.
Changed my Model, it is not using associations.Here is the Model that worked for me
Ext.define('SampleApp.model.Drupal', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'title',
mapping: 'node.title', // mapping worked
},
{
name: 'field_headshot',
mapping : 'node.field_headshot',
},
{
name: 'body',
mapping : 'node.body',
}
],
}
});
I'm new to sencha. I'm create MVC structure by use sencha architect, touch 2.2.x version.
I want to show nested data to a list control but I'm not sure how to define the tmp.
Here is sample of data return from server
{
"data":
[
{"AcctId": 1, "AcctNum": "A", "Alias": "aa"},
{"AcctId": 2, "AcctNum": "B", "Alias": "bb"},
{"AcctId": 3, "AcctNum": "C", "Alias": "cc"}
]
}
this is model, I define nested model
Ext.define('MyApp.model.Data', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.LoginAlias'
],
config: {
hasMany: {
model: 'MyApp.model.LoginAlias',
name: 'LoginAlias'
}
}
});
Ext.define('MyApp.model.LoginAlias', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'AcctId'
},
{
name: 'AcctNum'
},
{
name: 'Alias'
}
]
}
});
This is Stores to get data, It will be cross server data so I use JsonP
Ext.define('MyApp.store.MyJsonPStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Data'
],
config: {
autoLoad: true,
model: 'MyApp.model.Data',
storeId: 'MyJsonPStore',
proxy: {
type: 'jsonp',
url: 'http://localhost:8000/test/get_alias/',
reader: {
type: 'json'
}
}
}
});
Finally the List
Ext.define('MyApp.view.MyList', {
extend: 'Ext.dataview.List',
config: {
store: 'MyJsonPStore',
itemTpl: [
'<div>List Item {AcctId}</div>'
]
}
});
I can see that the Store can get data from server in Sencha Architect by click on the "eye" icon next to the Store.
I try the List tpl with data.AcctId or change List store to MyJsonPStore.data but all not work.
Please help, thanks very much.
p/s: I try with non-nested model, and the List work ok. And this is the main js file, In case it needed
Ext.Loader.setConfig({
});
Ext.application({
models: [
'Data',
'LoginAlias'
],
stores: [
'MyJsonPStore',
'MyStore'
],
name: 'MyApp',
launch: function() {
Ext.create('MyApp.view.MyList', {fullscreen: true});
}
});
1. Data structure
Not sure it's useful to define MyApp.model.Data as it's only the root of your list of data. So you could give away the hasMany logic.
2. Data representation
Ext.dataview.List is designed to show simple lists only. For nested lists, consider extending Ext.dataview.NestedList. (but if 1. is true, you won't need it).
3. Data access
To get direct access to the data you need to display, simply add rootProperty: 'data' to your proxy's reader config object:
proxy: {
type: "jsonp",
url: 'http://server.ext/path/to/MyApp/app/data/sample.ashx',
reader: {
type: "json",
rootProperty: 'data'
}
}
So, I have a problem using Sencha ExtJs 4.1 Associations.
I have something like:
Models
Ext.define('Tpl.model.User', {
extend: 'Ext.data.Model',
requires: ['Tpl.model.PostTemplate'],
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' },
{ name: 'postTemplate', type: 'int' }
],
associations: [
{ type: 'belongsTo', name: 'postTemplate', model:'Tpl.model.PostTemplate', associationKey: 'postTemplate', primaryKey: 'id', foreignKey: 'postTemplate' }
]
});
and
Ext.define('Tpl.model.PostTemplate', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'blah', type: 'string' }
],
associations: [
{ type: 'hasMany', model: 'Tpl.model.User' }
]
});
Stores
Ext.define('Tpl.store.Users', {
extend: 'Ext.data.Store',
model: 'Tpl.model.User',
autoLoad: true,
proxy: {
type: 'rest',
url: '../users',
reader: {
type: 'json',
root: ''
},
writer: {
type: 'json'
}
}
});
Ext.define('Tpl.store.PostTemplate', {
extend: 'Ext.data.Store',
model: 'Tpl.model.PostTemplate',
autoLoad: true,
proxy: {
type: 'rest',
//appendId: true,
url: '../postTemplates/',
reader: {
type: 'json',
root: ''
},
writer: {
type: 'json'
}
}
});
The problem is that I'm getting a POST like this:
{
"postTemplate": 1,
"id": 0,
"name": "foo"
}
But I need a POST like this:
{
"postTemplate": {
"id": 1,
"blah": "foo"
},
"id": 0,
"name": "bar"
}
Also, the assessor function like "setPostTemplate" doesn't exist and I think it should be created automatically.
Already tried to something like " record.data.postTemplate = (...) " but I got an infinite loop throwing an execption...
Can someone please advise? Also, if you need something else that could be useful for the answer let me know.
Thanks!
Out of the box the Associated objects are not serialized back to the server as you expect them . This issue has been brought up many times. The best thing might be to follow this thread:
http://www.sencha.com/forum/showthread.php?141957-Saving-objects-that-are-linked-hasMany-relation-with-a-single-Store
This thread talks about overriding getRecordData in the JSON writer class.