ExtJS localstorage proxy model/store issue - extjs

I'm using ExtJS 5.1.0 and running into a strange problem.
I have the following model:
Ext.define('cardioCatalogQT.model.Load', {
extend: 'Ext.data.Model',
config:{
idProperty: 'id',
fields: [
{name: 'key', type: 'string'},
{name: 'comparator', type: 'string'},
{name: 'value', type: 'string'},
{name: 'type', type: 'string'}
]
}
});
And the Store:
Ext.define('cardioCatalogQT.store.Payload', {
extend: 'Ext.data.Store',
alias: 'store.Payload',
// add package.framework=ext to .sencha/app/sencha.cfg
config:{
model: 'cardioCatalogQT.model.Load',
storeId: 'Payload',
autoLoad: true,
proxy: {
type: 'localstorage'
}
}
});
When I add a record to the store:
var payload = Ext.create('cardioCatalogQT.store.Payload');
payload.add({
type: 'dx',
key: item.data.code,
comparator: 'eq',
value: item.data.description
});
payload.sync();
The data in localstorage look like all the records except for #7 and #11 in the attached image
However, when I add the field elements to the store like this:
Ext.define('cardioCatalogQT.store.Payload', {
extend: 'Ext.data.Store',
alias: 'store.Payload',
// add package.framework=ext to .sencha/app/sencha.cfg
config:{
idProperty: 'id',
fields: [
{name: 'type', type: 'string'},
{name: 'key', type: 'string'},
{name: 'comparator', type: 'string'},
{name: 'value', type: 'string'}
] ,
//model: 'cardioCatalogQT.model.Load',
storeId: 'Payload',
autoLoad: true,
proxy: {
type: 'localstorage'
}
}
});
I get the desired results in 7 and 11.
One other issue, is instead of giving an actual name to the model record, I get the very not useful name of ext-data-proxy-localstorage-N for the model instance.
Also, I am getting this error when referencing the model via the store:
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (cardioCatalogQT.model.Load, line 0)
I have done a sencha app build and no errors were thrown.
Any idea as to what I am doing wrong (I am basically doing what I've done with Sencha Touch, where I had much success)? Is this a bug, perhaps?

Issue was for ExtJS, to get the desired name on the store, you have to specify and id in the proxy:
proxy: {
type: 'localstorage',
id : 'payload'
}
Now, the model instances in my localstorage are showing up as desired, and I can query them using standard methods, like findRecord. Good times!
Moral of the story: ExtJS has different behaviors than Touch

Related

Extjs two instances of stores not using different models

edit http://jsfiddle.net/zns6B/4/ Added js fiddle link and running into a cannot get 'Fields' of undefined now
edit2 So i found that the second grids store model is correct with Sc.Model.B. But the records in the store have ids that are Sc.Model.A . So my store model is set to Sc.Model.B but the store is using Sc.Model.A . It still gets stores the data in the store but only as if the model was set to Sc.Model.A in the first place.
edit3 I have take all the creation of instance out of my ListGrid. I have instead added them when creating the list grid. I have added the following. This does not work either. I am at a lose for what to do.
var obj1 = Ext.create('Sc.ListGrid',{
title: "first Component",
foo: true,
id: 'firstGrid',
myStore: Ext.create('My.Store.MyStore',{model:Ext.create('My.Model.Model'});
renderTo: 'renderToMe1'
});
I am trying to generate these two grids. When foo == true i want it to generate a store with model A. When it equals false i want it to use model B. I have tried to just specifically add the My.Model.MyModel but that does not work. The second grid will somehow inherit the first models model. I have changed it just to try and use fields instead of using the model at all but the second grid still uses the first grids.
I have also tried declaring the Stores inside the initComponent as well but i get the same result either way.
var obj1 = Ext.create('Sc.ListGrid',{
title: "first Component",
foo: true,
id: 'firstGrid',
renderTo: 'renderToMe1'
});
var obj2 = Ext.create('Sc.ListGrid',{
title: "second Component",
foo: false,
renderTo: 'renderToMe2'
});
Sc.ListGrid
Ext.define('Sc.ListGrid', {
extend: 'Ext.grid.Panel',
title: 'Grid',
store: Ext.data.StoreManager.lookup('bleh'),
requires: ['stuff'],
columns: [
{ text: 'id', dataIndex: 'id' },
],
config:{
foo: null,
},
initComponent: function(){
if(this.foo == true){
Ext.apply(this,{
store: this.buildStore1()
});
}
if(this.foo == false){
Ext.apply(this,{
store: this.buildStore2()
});
}
this.callParent();
},
buildStore1:function(){
return Ext.create('Sc.Store.League.LeagueStore',{url:'somewhere',fields:["S"]});
},
buildStore2:function(){
return Ext.create('Sc.Store.League.LeagueStore',{url:'somewhere',fields:["A"]});
}
});
Also an example of a model i am trying to use as well.
Ext.define('Sc.Model.A', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'type', type: 'string'},
{name: 'gamename', type: 'string'}
]
});
Ext.define('Sc.Model.B', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'type', type: 'string'},
{name: 'gamename', type: 'string'},
{name: 'something1', type: 'string'},
{name: 'something2', type: 'string'},
]
});
It will create both grids and load the data from my webservice. When i check the grid with Sc.Model.B's data it will have id and type. But will not have any data for something1, and something2. My webserivce is returning json and all values are entered. There are no nulls. If i Ext.getCmp('firstGrid').getStore().getData(0); If i use Ext.getCmp('firstGrid').getStore() and check the model name. It shows Model B but reflects A
Do you need it to be done in the initComponent()??
This is a fiddle I saved from a while ago when I was trying to do something similar. If you need help tweaking it let me know and ill update it.
The main thing to note is the grid.reconfigure(store,columns);
That will change the grid's store and columns appropriately.
http://jsfiddle.net/zqG55/1/
The issue was that the proxy wasn't being set or created properly because the proxy model was referencing the previous model instance. This is my solution
var themodel = 'A.Model.SomeModel';
var myProxy = new Ext.data.proxy.Ajax({
model: themodel,
url: url,
reader: {
type: 'json',
}
});
Ext.apply(this,{
columns: modelColumns.columns,
store: Ext.create('M.Store.MyStore',{
model: themodel ,
autoLoad: true,
proxy: myProxy
})
});

Where's my EXT JS 4 model data?

Using Ext JS 4.1....
I have a grid that displays a bunch of Model instances, although only some of the fields are displayed. I then have a double-click listener where I would like to load the entire record into a form for editing. In the double-click listener I do not see the data in my hasMany association although the json data is being returned according to Firebug's Net display where I see the response from the server call. Is there something wrong with my model or am I going about this wrong?
Request.js
Ext.define('Request', {
extend: 'Ext.data.Model',
requires: ['PointOfContact'],
fields: [
{name: 'id', type: 'int'},
{name: 'project', type: 'string'},
{name: 'purpose', type: 'string'},
{name: 'status'},
{name: 'additionalInfo', type: 'string'}
],
hasMany: [{
model: 'PointOfContact',
name: 'pointOfContacts',
foreignKey: 'id',
associationKey: 'pointOfContacts'
}],
proxy: {
type: 'rest',
url: '/web/project/rest/request/',
reader: { type: 'json' },
writer: { type: 'json' }
}
});
PointOfContact.js
Ext.define('PointOfContact', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'fullName', type: 'string'},
{name: 'email', type: 'string'},
{name: 'phone', type: 'string'}
]
});
Requests.js
Ext.define('Requests', {
extend: 'Ext.data.Store',
model: 'Request',
autoLoad: true
});
RequestsView.js
Ext.define('RequestsView', {
extend: 'Ext.grid.Panel',
title: 'All Requests',
store: 'Requests',
viewConfig: {
singleSelect: 'true',
listeners: {
itemdblclick: function(dataview, record, item, index, e) {
console.log(record.get('project'));
console.log(record.get('purpose'));
console.log(record.get('status'));
console.log(record.get('additionalInfo'));
console.log(record.get('pointOfContacts'));
var comp = Ext.ComponentQuery.query('requestForm');
comp[0].getForm().loadRecord(record);
var mainPanel = Ext.ComponentQuery.query('mainpanel');
mainPanel[0].getLayout().setActiveItem('requestForm');
}
}
},
columns: [
{header: 'Project', dataIndex: 'project', flex: 1},
{header: 'Purpose', dataIndex: 'purpose', flex: 1},
{header: 'Status', dataIndex: 'status', flex: 1}
]
});
So in the console I see the values for project, purpose, status and additionalInfo but I get "undefined" for pointOfContacts.
Any suggestions?
UPDATE WITH FINAL WORKING CODE:
Here is the working code I used to retrieve the pointofContacts and load a grid on my form panel with the pointOfContacts
...
itemdblclick: function(dataview, record, item, e) {
var comp = Ext.ComponentQuery.query('requestForm');
comp[0].getForm().loadRecord(record);
Ext.getCmp('pocGrid').reconfigure(record.pointOfContacts());
var mainPanel = Ext.ComponentQuery.query('mainpanel');
mainPanel[0].getLayout().setActiveItem('requestForm');
}
....
Has many associations are not parsed in to associated records by default. Especially for the grid - as that is supposed to be a flat data view. Model docs show you how to setup associations but don't say anything about creating instances for you :)
There are links to usage of has many (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.association.HasMany) from the Model docs. Unfortunately the usage is not what you expect it to be. Essentially it is designed to fetch the records on demand by calling their store to load.

EXTJS Combox - Store does load but doesn't show

Given the following javascript:
var fo = Ext.create('Ext.form.Panel', {
layout:'box',
...
items: [{
xtype: 'combobox',
valueField: 'id',
displayField: 'organizationtype',
store: {
storeId: 'zaza',
fields: [{name: 'id'}, {name: 'organizationtype'}],
root: 'data',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/apps/crm_organizations/orgtype/',
reader: {
type: 'json'
}
}
},
fieldLabel: 'Type relation',
name: 'organizationtype',
queryMode: 'local',
},
...
This panel contains - among other fields - also this combobox. I can see with wireshark that the url '/apps/crm_organizations/orgtype/' is actually queried. However the combobox doesn't show any values. Has this anything to do with the fact that I'm lazy loading the combobox?
This is the response on the JSON request:
{data: [ {id:"1" ,organizationtype:"Customer"}
,{id:"2" ,organizationtype:"Relation"}
,{id:"3" ,organizationtype:"Supplier"}
,{id:"4" ,organizationtype:"Unknown"} ]}
You have to set the root to the json reader you are using, Default is "", your's should be :
reader: {
type: 'json',
root: 'data'
}
Also you might consider replacing the fields configuration with a model object.(from docs)fields: In general this configuration option should be avoided, it exists for the purposes of backwards compatibility
Change combobox mode from local to remote mode: 'remote' and use json store:
store: {
xtype: 'jsonstore',
url: '/apps/crm_organizations/orgtype/',
autoLoad: true,
idProperty: 'id',
root: 'data',
fields: ['id','organizationtype'],
},
mode: 'remote'
In your store ,you missing the root property
store: {
storeId: 'zaza',
fields: [{name: 'id'}, {name: 'organizationtype'}],
root: 'data',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/apps/crm_organizations/orgtype/',
reader: {
type: 'json',
root:'data'
}
}
}
and if your combo is query information across domains,then use jsonp configuration and use remote query for better performance

Including a data Store makes the app not load

I can't get my application to work using MVC architecture.
Here is the code:
app.js
Ext.application({
name: CONFIG.APP_NS,
appFolder: '../js/app',
autoCreateViewport: true,
/*
models: ['User'],
stores: ['Users'],
//*/
controllers: ['Main', 'Tab', 'Import', 'Export', 'Predict', 'Admin']
});
Import.js (controller)
Ext.define(CONFIG.APP_NS+'.controller.Import', {
extend: 'Ext.app.Controller',
//stores: ['Users'], //Uncommenting this makes the application not load at all
models: ['User'],
views: ['Import.Window', 'Import.Toolbar', 'Import.Grid'],
init: function(){
...
},
...
});
User.js (model)
Ext.define(CONFIG.APP_NS+'.model.User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'username', type: 'string'},
{name: 'password', type: 'string'},
{name: 'salt', type: 'string'},
{name: 'firstName', type: 'string'},
{name: 'lastName', type: 'string'},
{name: 'email', type: 'string'},
{name: 'admin', type: 'boolean'},
{name: 'authenticated', type: 'boolean'}
],
hasMany: {model: CONFIG.APP_NS+'.model.Roles', name: 'roles'},
proxy: {
type: 'ajax',
url: 'model/users',
reader: {
type: 'json'
}
}
});
Ext.define(CONFIG.APP_NS+'.model.Roles', {
extend: 'Ext.data.Model',
fields: [
{name: 'role', type: 'string'}
],
belongsTo: CONFIG.APP_NS+'.model.User'
});
Users.js (store)
Ext.define(CONFIG.APP_NS+'store.Users', {
extend: 'Ext.data.Store',
requires: CONFIG.APP_NS+'.model.User',
model: CONFIG.APP_NS+'.model.User'
});
Grid.js (view)
Ext.define(CONFIG.APP_NS+'.view.Import.Grid', {
extend: 'Ext.grid.Panel',
alias: 'widget.importgrid',
initComponent: function() {
this.store = Ext.create('Ext.data.Store', { //Works fine with the code as it is
model: CONFIG.APP_NS+'.model.User',
proxy: {
type: 'ajax',
url: 'model/users',
reader: {
type: 'json'
}
}
});
//*/
//this.store = Ext.create(CONFIG.APP_NS+'.store.Users', {});
this.columns = [
{header: 'Name', dataIndex: 'username', flex: 1},
{header: 'Email', dataIndex: 'email', flex: 1}
];
this.callParent(arguments);
this.store.load();
}
});
I have tried almost every combination of stores: in different files possible, nothing seems to do the trick. If I do not include the store anywhere, I get the error Object is not a function (or TypeError: Cannot call method 'on' of undefined if defined outside of the initComponent in the view) somewhere in internal extjs files. It seems that even if I copy the structure from the tutorial examples, it still does not work, so I must be missing something.
What am I doing wrong?
Thank you for your time.
EDITS:
I am running this code on Wamp (localhost). The server has both ExtJS4 and Symfony installed and running.
Updated error message.
Fixed a typo in the Model, see comments.
(I see you have the stores commented out in the app.js. Is this intentional?)
I ran into a similar problem.. as soon as i added the store to my app.js and view.js (a grid panel), my app stopped working.
I'm pretty sure I fixed it by adding the stores (all of them) to the controller and the app.js. Ok.. just checked again, and I get a different error message if the store was missing from controller.js: "Uncaught TypeError: Cannot call method 'on' of undefined" (this is on chrome). Slightly different error message.
Also, consider commenting out the this.store.load().. i.e. remove the server data-access variable - (one thing at a time.)
I found the bug.
Users.js (store)
Ext.define(CONFIG.APP_NS+'store.Users', {
extend: 'Ext.data.Store',
requires: CONFIG.APP_NS+'.model.User',
model: CONFIG.APP_NS+'.model.User'
});
First line should be:
Ext.define(CONFIG.APP_NS+'.store.Users', {
I was missing a period before store.
Molecule Man's comment made me recheck all the definitions, thank you.

How to access nested models from store in ExtJs 4

I just downloaded the final version of ExtJs 4 and I'm trying to implement some things using new Model approach.
For instance I have a model named SetupModel, it has 2 nested models Users, Reports.
I create new store and I set the Model property of the store = SetupModel.
The question is - how can I access my nested properties after data was loaded into the store?
I need something like myStore.data.Users(), but is incorrect.
Any thoughts?
When you define your model, you need to provide the necessary association with the nested models. Since, you have not provided your code. Here is an example:
My Product Model:
Product = Ext.define('Product',{
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'user_id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'price', type: 'float'}
],
proxy: {
type: 'localstorage',
id: 'products'
}
});
My User Model:
User = Ext.define('User',{
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'gender', type: 'string'},
{name: 'username', type: 'string'}
],
associations: [
{type: 'hasMany', model: 'Product', name: 'products'}
],
proxy: {
type: 'localstorage',
id : 'users'
}
});
Now, if you have a instance of User model with products. Here is how you can access the products:
var productStore = user.products();
Note that user.products() returns a Ext.data.Store. Now, you can traverse or filter or find your product record. Here is how I got my first product's name:
productStore.getAt(0).get('name');

Resources