I´m using Sencha Touch 2 and have defined a model like this:
Ext.define('csx.model.Profile', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'firstname',type: 'string'},
{name: 'lastname', type: 'string'},
],
hasMany: [
{model: 'Telephone', name: 'telephones'},
{model: 'Email', name: 'emails'},
],
},
doSomething: function () {
var firstname = this.get('firstname'); //returns null
var phones = this.telephones(); // throws a TypeError
},
});
Inside my function doSomething I am trying to access the values of the model and the models associated with the hasMany property. The getfunction only returns null and when I try to access the associated models I only get a TypeError saying that the object doesn´t have a telephones function. But when I look at the Sencha Touch 2 guides UsingModels on how to use models it says that the hasMany associations are accessible trough a function resembling the name I specified (telephones).
So how do I access the field values and the associated models inside a model instead?
You should change the model properties in the 'hasMany' config of your model to reflect the full name of your models:
hasMany: [
{model: 'csx.model.Telephone', name: 'telephones'},
{model: 'csx.model.Email', name: 'emails'},
],
That is, supposing you have defined your models Telephone and Email like this:
Ext.define('csx.model.Telephone', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'number', type: 'string'},
],
});
Ext.define('csx.model.Email', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'address', type: 'string'},
],
});
Then, if you create an instance of your 'Profile' model:
var profile = Ext.create('csx.model.Profile', {firstname:'John',lastname:'Deere'});
you can access your fields like this:
profile.get('firstname');
profile.get('lastname');
and the 'telephones' and 'emails' stores from the hasMany associations like this:
profile.telephones()
profile.emails()
The fact that your 'firstname' field had a null value is because you didn't instantiate your model. The fact that the 'telephones()' function was not created automatically as stated in the docs is because of the wrong 'model' configuration as explained in the beginning of this answer.
Hope this helps.
Related
I have a piece of code in a Sencha Touch v2 controller as shown below. When this code is ran the count after the store.add is (6), the counter after the store.sync is (0) and the store.sync is succeeding.
NOTE: items holds 6 records received from a JsonP proxy, no errors are shown in the console and everything acts as though it was a full success.
requires: [
'Ext.data.proxy.JsonP',
'Ext.data.proxy.Sql'
],
config: {
models: ['Convention'],
stores: ['Conventions']
},
// ***additional code*** //
store.setProxy({
type: 'sql',
database: 'app',
table: 'Conventions'
});
store.removeAll();
store.sync({
success: function(batch){
store.add(items);
console.log("Count before: " + store.getCount()); << Shows (6)
store.sync({
failure: function (batch, options) {
console.log('Convention Sql failure');
},
success: function(batch,options){
console.log("Count after: " + store.getCount()); << Shows (0)
console.log("Convention Sql success");
store.load();
Ext.Viewport.unmask();
}
});
}
});
The model is show here
extend: 'Ext.data.Model',
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' },
{ name: 'logoId', type: 'string' },
{ name: 'seasonId', type: 'string'},
{ name: 'viewed', type: 'string'},
{ name: 'dateCreated', type: 'string'},
{ name: 'dateUpdated', type: 'string'}
]
}
and the store is here
extend: 'Ext.data.Store',
requires: [
'Ext.data.proxy.Sql'
],
config: {
model: 'app.model.Convention',
autoLoad: false,
sorters:[{
property: 'name',
direction: 'ASC'
}],
proxy: {
type: 'sql',
database: 'app',
table: 'Conventions'
}
}
After much research it seems that Sencha recently changed some of their code on how they handle IDs. As such, if you are using code examples previous to this change you will get errors when you try to save to the ID field.
Sencha has added the clientIdProperty that you can add to the writer of a proxy and directly to the model.
Reference: http://docs.sencha.com/touch/2.4/2.4.2-apidocs/#!/api/Ext.data.Model-cfg-clientIdProperty
The name of a property that is used for submitting this Model's unique client-side identifier to the server when multiple phantom records are saved as part of the same Operation. In such a case, the server response should include the client id for each record so that the server response data can be used to update the client-side records if necessary. This property cannot have the same name as any of this Model's fields.
As such, my code above will have the following changes to the following where 'siteId' is my id being passed from the Json request and the ID on my server for the record.
model
idProperty: 'id',
clientIdProperty: 'siteId',
identifier: 'uuid',
Controller
store.setProxy({
type: 'sql',
database: 'app',
table: 'Conventions',
writer: {
clientIdProperty: 'siteId'
}
});
Im trying to populate a custom component using a store (actually a store with local data) in a Sencha Touch 2 project.
My idea is to create one custom component for each element in the store, but actually nothing happens.
I have tried several things but anything works, could you help me? I have done an example to show the problem:
model:
Ext.define('project.model.city', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'country', type: 'string'},
{name: 'city', type: 'string'}
]
}
});
store:
Ext.define('project.store.cities', {
extend: 'Ext.data.Store',
requires: ['project.model.city'],
model: 'project.model.city',
autoLoad: true,
data: [
{ country: 'Germany', city: 'Berlin' },
{ country: 'Italy', city: 'Rome' }
]
});
View with store:
Ext.define('project.view.cityAll', {
extend: 'Ext.Panel',
xtype: 'cityAllView',
config: {
items:[{
xtype: 'cityItemView',
store: 'project.store.cities',
}]
}
});
Custom component View:
Ext.define('project.view.cityItem', {
extend: 'Ext.Panel',
xtype: 'cityItemView',
config: {
items: [{
itemTpl: '{city}'
}]
}
});
You need to assign store to cityItemView instead of cityAllView. cityItemView is having template specified and needs to be loaded with data.
Ext.define('project.view.cityItem', {
extend: 'Ext.Panel',
xtype: 'cityItemView',
config: {
items: [{
xtype:'list',
itemTpl: '{city}'
store:'project.store.cities'
}]
}
});
If you want to set data into panel, then you'd need to call setData(). A panel can not load data from store directly. You can use list view instead so show city, country pair. cityView no longer needed store property that way.
Give this a try.
You can add load listener in store which would loop through records and create as many panels:
listeners : {
load: function( me, records, successful, operation, eOpts ){
var plist = [];
var cv = Ext.Create('project.view.cityAll');
if(successful){
var data = records[i].getData();
for(var i=0; i<records.length; i++){
plist.push({
xtype : 'cityItemView',
data : data
});
}
cv.add(plist);
}
// Now add cv to viewport or wherever you want
}
}
You have to change cityItemView to use data whichever way you want. If you are using initialize method you can access it like this.config.data
I've got these models :
Ext.define('TestApp.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'username', type: 'string'},
],
proxy: {
type: 'localstorage',
},
},
});
Ext.define('TestApp.model.Config', {
extend: 'Ext.data.Model',
config: {
hasOne : {model: 'TestApp.model.User', name: 'user'},
proxy: {
type: 'localstorage',
},
}
});
I've tried to save a config entry like this :
var david = Ext.create('TestApp.model.User', {username: 'david'})
david.save();
var config = Ext.create('TestApp.model.Config');
config.setUser(david);
config.save();
When I restart the application, I have my user entry saved and my config entry saved but, my association is not saved:
config.getUser() -> I get undefined
According to Mitchell Simoens storing associated data isn't supported.
Unsure if it helps in your case, but an approach is sketched (that approach also seems to adress my own current (unrelated) problem).
Hope it helps
I'm using ExtJS 4.0.7 with its standard MVC architecture. I have a grid with custom store and model classes. The data is loaded remotely via store.load(). I'm using ext-dev.js for debug purposes with dynamic dependency loading.
The app loads fine with no errors in Chrome's console. But the problem is that the records in my store have exactly the same data as provided by my AJAX call, regardless of what fields I have in my model. I even tried renaming and deleting fields but Ext is not paying attention.
Browsing my store object using the console shows that the records all have their own custom runtime-generated model class named Ext.data.reader.Json-Modelext-gen1141. Here is the gist of my code:
My model:
Ext.define('MyApp.model.FooModel', {
extend: 'Ext.data.Model',
idProperty: 'column1',
fields: [
{name: 'column1', convert: function(value, record) {
return value + ' TEST-TEST-TEST';
}},
'column2',
'column3'
]
});
My store:
Ext.define('MyApp.store.FooStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.FooModel',
autoLoad: false,
proxy: {
type: 'ajax',
url: '/blah/blah',
reader: {
type: 'json'
}
}
});
My grid:
Ext.define('MyApp.view.FooGrid', {
extend: 'Ext.grid.Panel',
alias: 'fooGrid',
store: 'FooStore',
columns: [{
text: 'Column 1',
dataIndex: 'column1',
flex: 1
},{
text: 'Column 2',
dataIndex: 'column2',
flex: 1
},{
text: 'Column 3',
dataIndex: 'column3',
flex: 1
}]
});
My controller:
Ext.define('MyApp.controller.Foo', {
extend: 'Ext.app.Controller',
views: ['FooGridFrame'],
models: ['FooModel'],
stores: ['FooStore'],
init: function() {
this.control({
'fooGrid': {
activate: function(grid) {
grid.getStore().load();
}
}
});
}
});
I can't tell what I'm doing wrong. Any ideas?
It turns out that the AJAX backend (written by another dev for Ext3) was providing some config data via a metaData property. I didn't know that Ext's Store paid any attention to this. My problem was solved by updating the backend to omit the metaData property.
It probably would have also worked to update metaData to provide the appropriate config that I needed, but I'm refactoring to make all the UI config happen in the client.
I have a form and a grid to submit a query,like this:
items:[
{
fieldLabel: 'query the month',
xtype : 'textfield',
name : 'query_year_month',
id: 'query_year_month'
} ],
buttons: {
text: 'submit',
formBind: true, //only enabled once the form is valid
disabled: false,
handler: function() {
//some code
}
var store = Ext.create('Ext.data.Store', {
model: //uncertain,
region : 'south',
pageSize: 15,
proxy: {
type: 'ajax',
url : 'brokee/brokagequery/',
reader: {
type: 'json',
root: 'users'
}
},
autoLoad: false
});
I'd like to load data to a grid after submiting the form.The return data is a json
structure,I don't want to define the static model bind to the store and neither the grid columns,because the data returned is uncertained. The store model and grid columns should be generated from the json data,
for example: json: {'field1':data1, 'field2':data2}
the model should be generated like this:
Ext.define('somemodel', {
extend: 'Ext.data.Model',
fields: [
{name: 'field1', type: 'string'},
{name: 'field2', type: 'string'}
]
});
In the official demo, the store and model are predefined, then call the store.load method to refresh the grid throuth the proxy.But how can I do that when the store and model need to be generated?
When you have your json loaded, you can create store store/model like this.... use record .raw to extract values and :
Ext.create("Ext.data.JsonStore",{
id:record.raw.storeID,
model: Ext.define('App.dataGridModel', {
extend: 'Ext.data.Model',
fields: [record.raw.id, record.raw.first]...
})
...
});
the same with the grid etc..