ExtJs:Initializing a global variable - extjs4

I have a global variable which needs to be initialized when the store is loaded and needs to use that value in another store as follows
var cp = 0;
Ext.onReady(function() {
Ext.define('Init', {
singleton: true,
cp: 0
});
Ext.define('loggedUserList', {
extend: 'Ext.data.Model',
fields: [
'id',
'name'
]
});
loggedUser = Ext.create('Ext.data.Store', {
model: 'loggedUserList',
autoLoad: true,
proxy: {
type: 'ajax',
url: url+'/lochweb/loch/users/getLoggedUser',
reader: {
type: 'json',
root: 'provider'
},
listeners: {
load: function(loggedUser) {
Init.cp = loggedUser.getAt(0).data.id;
}
}
});
});
I am using the value of cp in another url as follows: url: url + '/lochweb/loch/vocabulary/getVocabularyByProvider?providerId=' + Init.cp,
Ext.define('vocbList', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
mapping: 'id'
},
{
name: 'code',
mapping: 'code'
}
]
});
var vocabulary = Ext.create('Ext.data.Store', {
model: 'vocbList',
autoLoad: true,
proxy: {
type: 'ajax',
url: url+'/lochweb/loch/vocabulary/getVocabularyByProvider?providerId='+Init.cp,
reader: {
type: 'json',
root: 'Vocabulary'
}
}
});
but its value is still 0. I tried using(cp, Init.cp). How to assign its value form store so that it can be reused?
Thanks

Store loads data asynchronously, so you can't be sure that Init.cp will be initialized with a new value before the other store is been loaded.
Try with this:
var cp=0;
Ext.onReady(function(){
Ext.define('Init', {
singleton: true,
cp: 0
});
Ext.define('vocbList', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: 'id' },
{ name: 'code', mapping: 'code' }
]
});
var vocabulary = Ext.create('Ext.data.Store', {
model: 'vocbList',
proxy: {
type: 'ajax',
reader: {
type: 'json',
root: 'Vocabulary'
}
}
Ext.define('loggedUserList', {
extend: 'Ext.data.Model',
fields: ['id','name']
});
loggedUser = Ext.create('Ext.data.Store', {
model: 'loggedUserList',
autoLoad: true,
proxy: {
type: 'ajax',
url : url+'/lochweb/loch/users/getLoggedUser',
reader: {
type: 'json',
root: 'provider'
}
},
listeners: {
load:function(loggedUser){
Init.cp = loggedUser.getAt(0).data.id;
vocabulary.getProxy().url = url+'/lochweb/loch/vocabulary/getVocabularyByProvider?providerId='+Init.cp;
vocabulary.load();
}
}
});
});
As you can see, you have to set the url of the vocabulary proxy dynamically when the first store is just loaded and then load the store.
Cyaz

Here you declare loggedUser = Ext.create('Ext.data.Store', {
model: 'loggedUserList',
autoLoad: true,...} with Init.cp is assigned with some data in load(). But you cannot confirm that Init.cp has actually had value at the time you declare variable vocabulary (i.e. maybe loggedUser has not yet fully been loaded). So it still be 0 in the url.
To confirm, you should move codes of vocbList and vocabulary into a function:
function vocabularyLoad() {
Ext.define('vocbList', {...});
var vocabulary = ...
}
and use the function this way in loggedUser:
loggedUser = Ext.create('Ext.data.Store', {
...
listeners: {
load:function(loggedUser){
Init.cp = loggedUser.getAt(0).data.id;
vocabularyLoad();
}
}
});
But actually, this refactoring makes the assignment of Init.cp redundant because you can directly pass the value of loggedUser.getAt(0).data.id into the defined function.

Related

Extjs4 - Defining methods on a model

According to the docs, I should be able to define functions on a Model, and then call the function on instances of that model.
At least in the case where I load the model from a proxy, its not working.
My model:
Ext.define('MyApp.model.Detail', {
extend: 'Ext.data.Model',
fields: [
'someField',
'anotherField',
],
someFunction: function() {
//do something
},
proxy: {
type: 'ajax',
url: 'http://example.com/details',
reader: {
type: 'json',
root: 'data',
totalProperty: 'total',
successProperty: 'success',
}
},
});
Store:
Ext.define('MyApp.store.DetailStore', {
extend: 'Ext.data.Store',
storeId: 'detailStore',
model: 'MyApp.model.Detail',
});
Controller:
Ext.define('MyApp.controller.appController', {
extend: 'Ext.app.Controller',
init: function() {
this.getDetailStoreStore().addListener('load', this.newDetails, this);
},
stores: ['DetailStore'],
models: ['Detail'],
views : ['DetailView], //exists, not copied into question
newDetails: function(store, records) {
var details = records[0].data;
details.someFunction(); // Uncaught TypeError: Object #<Object> has no method 'someFunction'
}
});
The error happens in the newDetails function, when calling data.someFunction().
Do I have the wrong expectation?
The function exists on the model, so you would call:
records[0].someFunction();

Adding a AJAX response data to a store

How to add a data to a json store if my data is coming from a back end AJAX call.
my store is as follows .
Ext.define('MyApp.store.GeographyMasterStore', { extend: 'Ext.data.Store',
requires: [
'MyApp.model.GeographyMasterModel'
],
config: {
model: 'MyApp.model.GeographyMasterModel',
storeId: 'geographyMasterStore',
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
}
}
});
And my model is as follows:
Ext.define('MyApp.model.GeographyMasterModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'Code'
},
{
name: 'Description'
},
{
name: 'Level_Code',
mapping: 'Level Code'
},
{
name: 'Name'
}
]
}
});
If I add the data like this
var geographyMasterStore = Ext.getStore('geographyMasterStore');
geographyMasterStore.add(<data from backend AJAX call>);
it does not show me the mapped field i.e. Level_Code
Usually I when add a record to the store like this :
Ext.create('App.model.MyModel', JSON.parse(response.responseText);
Where response is the response from an Ext.Ajax.request
Hope this helps
You need create a model:
var record = Ext.create('model.GeographyMasterModel', Ext.JSON.decode(response.responseText));
save the model:
record.save()
reload the store:
geographyMasterStore.load()

Sencha Touch Grouper Property Conversion

I have a list reading from a Json store which contains a grouper on a field of type int. This field is called "req" in the sample model below. However, rather than group by the int value, I would like to assign a text value instead, so for example, in case of "1" I would group by "Yes" and in case of "0" I would group by "No". The conversion can be hard coded as it will not change. Where do I make this conversion in my code? Thanks for your help
Ext.define('MyApp.store.MyStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.MyData'
],
config: {
model: 'MyApp.model.MyData',
storeId: 'MyStore',
proxy: {
type: 'ajax',
url: '/path/to/data.json',
reader: {
type: 'json',
rootProperty: 'items'
}
},
grouper: {
property: 'req',
sortProperty: 'req'
},
groupDir: 'DESC'
}
});
Model:
Ext.define('Mypp.model.MyModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'example',
type: 'string'
},
{
name: 'req',
type: 'int'
}
]
}
});
Add to the Model a calculated field with convert() function:
Ext.define('Mypp.model.MyModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'example',
type: 'string'
},
{
name: 'req',
type: 'int'
},
{
name: 'reqDisplay',
type: 'string',
convert: function (value, record) {
if (value == null) {
var req = record.get('req');
value = req ? 'Yes' : 'No'
}
return value;
}
}
]
}
});
... and use it instead
grouper: {
property: 'reqDisplay',
sortProperty: 'reqDisplay'
},
Cheers, Oleg

Populating Combobox from remote server

I have a combobox, i need to populate data from the server. In the server side i have the following data to be displayed.
PersonID
PersonFName
PersonLName
In the combobox, i need to display the text as PersonFName + PersonLName (Like James Smith- This is what it will display in the drop down) , and when a user selects a record, I need to display the corresponding PersonID (Like Person with PersonFName and PersonLName has the PersonID of 1) of that user.
I am unable to figure this out, here's my code
View :
{
xtype: 'combobox',
id: 'personcombo',
readOnly: false,
selectOnFocus: true,
forceSelection: true,
store: 'Person'
}
Store :
Ext.define('MyApp.store.PersonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Person'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'MyApp.model.Person',
proxy: {
type: 'ajax',
api: {
read: 'person.php',
create: 'person.php'
},
reader: {
type: 'array'
}
}
}, cfg)]);
}
});
Model :
Ext.define('MyApp.model.Person', {
extend: 'Ext.data.Model',
fields: [
{
name: 'PersonID'
},
{
name: 'PersonFName'
},
{
name: 'PersonLName'
}
]
});
I think your question is: how to display PersonFName + PersonLName in the combobox but keep the PersonID field as the value.
You should add a converted field which joins the first and last names in your data model and then make that one your combobox displayField config.
Though the other answer did bring up a good point that the defined store in your combo is Person but you are showing code for a store named PersonStore.
It would look something like this:
Model:
Ext.define('MyApp.model.Person', {
extend: 'Ext.data.Model',
fields: [
{
name: 'PersonID'
},
{
name: 'PersonFName'
},
{
name: 'PersonLName'
},
{
name: 'PersonName',
convert: function(value, record) {
return record.data.PersonFName + ' ' +
record.data.PersonLName;
}
}
]
});
Store:
// changed to "Person" instead of "PersonStore"
Ext.define('MyApp.store.Person', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Person'
],
model: 'MyApp.model.Person',
proxy: {
type: 'ajax',
api: {
read: 'person.php',
create: 'person.php'
},
reader: 'array'
}
});
View:
{
xtype: 'combobox',
id: 'personcombo',
readOnly: false,
selectOnFocus: true,
forceSelection: true,
store: 'Person',
valueField: 'PersonID',
displayField: 'PersonName' // the converted field
}
Your combobox has 'Person' as the store, but I don't see you create a store called Person anywhere. Try store: Ext.create('MyApp.store.PersonStore', {autoLoad: true}).
You can also simplify your store:
Ext.define('MyApp.store.PersonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Person'
],
model: 'MyApp.model.Person',
proxy: {
type: 'ajax',
api: {
read: 'person.php',
create: 'person.php'
},
reader: 'array'
}
});

ExtJs4 Model with different poxy url's

I have defined a model which I want to use twice but with a different url int he proxy (in fact only the id differs) But how can I manage this?
Ext.define('TesterModel', {
extend: 'Ext.data.Model',
autoLoad: false,
fields: [
{ name: 'prename', type: 'string' },
{ name: 'lastname', type: 'string' },
{ name: 'dept', type: 'string' },
{ name: 'rackName', type: 'string' },
{ name: 'rackIP' , vtype:'IPAddress'}],
proxy: {
type: 'ajax',
url: 'php/getData_db.php?id=',
reader: {
type: 'json',
messageProperty: 'message',
root: 'data',
}
},
constructor: function() {
UrlParams=document.URL.split("?");
if(UrlParams.length > 1) {
SingleUrlParams=Ext.Object.fromQueryString(UrlParams[1]);
this.proxy.url = this.proxy.url + SingleUrlParams.right;
console.log(this.proxy.url);
}
return this;
}});
Ext.ModelMgr.getModel('TesterModel').load(0, { // load user with ID of "0"
success: function(tester) {
var rightPanel=Ext.getCmp('rightTester');
rightPanel.loadRecord(tester); // when tester is loaded successfully, load the data into the form
}
});
I thought that the constructor will be done before loading, but nope, it is done after. It's weired to me.
Any hints, please?
(the main URL it's like: .../index.html?left=xx&right=yy )
so I want to fill up a panel on the left with the one id, and a panel on the right window side eith th right id.
Thanks!
Try .getProxy().url = "what/ever.php"