Sencha: Use store in other view - extjs

I have a store, which is created in a controller when login is successful. The code looks like this:
controller is login.js
//////////// create a JSONstore and load companies into it //////////////
var companies_data = new Ext.data.JsonReader({}, [ 'companyame']);
var storeCompanies = new Ext.data.JsonStore({
storeId: 'storeCompanies',
proxy: new Ext.data.HttpProxy({
type: 'GET',
url: url+'dashboard/?Uid='+uid+'&Ude='+ude,
reader: {
type: 'json',
root: 'root',
totalProperty: 'total'
},
headers: {
'Accept' : 'application/json;application/x-www-form-urlencoded',
'Content-Type' : 'application/x-www-form-urlencoded',
},
params: {
Uid: localStorage.uid,
Ude: localStorage.ude,
},
}),
reader: companies_data,
root: 'd',
type: 'localstorage',
autoLoad : true,
id: 'company_Id',
scope : this,
fields: ['companyname']
});
The code is a function, which is called on successful login and values are passed to it.
This works fine for as is, and the store is available to the login view
I need the store to be available to my mainview.
In my login.js controller, I have referred to the mainview like this:
Ext.define('axis3.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginView: loginview,
mainView: 'mainview',
chartView: 'chartview'
},
control: {
loginView: {
signInCommand: 'onSignInCommand'
},
mainMenuView: {
onSignOffCommand: 'onSignOffCommand'
}
}
},
but this does not seem to help.
When I use the following in my mainview
var companyStore = Ext.getStore('storeCompanies'); //
console.log('1-Number : ' + companyStore.getCount()); // Using getCount method.
var anotherCompany = { companyname: 'North Wells'};
companyStore.add(anotherCompany); //
console.log('2-Number : ' + companyStore.getCount()); // Using getCount method.
//////////////
Ext.define('axis3.view.Main', {
extend: 'Ext.form.Panel',
requires: ['Ext.TitleBar','Ext.data.Store'],
alias: 'widget.mainview',......................
I get this error:
TypeError: 'undefined' is not an object (evaluating
'companyStore.getCount')
How can I use my store in a different view?

Give storeId, try like this
var storeCompanies = Ext.create("Ext.data.JsonStore",{
storeId: 'storeCompanies', // add this line
proxy: new Ext.data.HttpProxy({
type: 'GET',
url: url+'dashboard/?Uid='+uid+'&Ude='+ude,
reader: {
type: 'json',
root: 'root',
totalProperty: 'total'
},
headers: {
'Accept' : 'application/json;application/x-www-form-urlencoded',
'Content-Type' : 'application/x-www-form-urlencoded',
},
params: {
Uid: localStorage.uid,
Ude: localStorage.ude,
},
}),
reader: companies_data,
root: 'd',
type: 'localstorage',
autoLoad : true,
id: 'company_Id',
scope : this,
fields: ['companyname']
});
Now try again with Ext.getStore('storeCompanies');

If have figured out the problem. The view is trying to use the store before it exists. The store is only created when a user logs in.
The solution I have decided to use is to create an empty store and then add data to it on successful login.
var anotherCompany = {companyname: 'Keep Groom'};
companiesStore2.add(anotherCompany); // Use the add function to add records or model instances.
This seems to work

Related

How can I create two UI elements from one store in extjs?

How can I add two different sets of data from the same store to be reflected in any two UI elements at the same time?
This is my store:
Ext.define('CPC.store.Website.StatisticChartByDate', {
extend: 'Ext.data.Store',
fields: [
'click',
'click2',
'ctr',
'true_ctr',
'ctr2',
'true_ctr2',
'click_fraud',
'click_fraud2',
...
],
proxy: {
type: 'ajax',
url: '/***/***/get-statistic-chart',
extraParams: {typeCP: Ext.util.Cookies.get('typeCP')},
reader: {
type: 'json',
root: 'data.chart',
statistic: 'data.statistic'
}
},
listeners:{
load:function (store, records) {
}
}
});
This is my json data:
{
"data":{
'statistic': {...}
'chart' : {...}
}
}
Image:https://www.dropbox.com/s/3zyxkzu5ky77710/statistic.png
please, help me..!
Many thanks..!
In my application, I have one store and I needed to swap out the proxy calls. I found this solution on StackOverflow, thanks to Saki:
flGridStore.getProxy().url = '../include/db_searchfilesbydate.php'; //<--Saki magic :)

The URL of an ajax proxy - Ext JS

I have a couple of questions about the url field of an ajax proxy, and Ext.Ajax.request
I'm getting a JSON response from an Ext.Ajax.request, and sending that data to a store. (I'm also trying to use the pagingToolbar, which is highly uncooperative at the moment)
Anyhow, the paging only seems to slightly work when I use an ajax proxy, however I'm not sure what to put in as the URL. Currently it's url: ''
var store = Ext.create('Ext.data.Store', {
storeId : 'resultsetstore',
autoLoad : false,
pageSize : itemsPerPage,
fields: [
{name : 'id', type : 'auto'},
{name : 'name', type : 'auto'},
{name : 'description', type : 'auto'}
],
proxy: {
type : 'ajax',
url : '???',
reader: {
type : 'json',
root : 'elements'
}
}
});
It seems the url reads data from a .json file in a specific directory (i.e. url: 'myData/data.json'), but there isn't any file like that to read from, as my response is coming back as a JSON Object.
And here is my request/response, which I parse and send to my store:
var request = Ext.Ajax.request({
url : 'MCApp', //here I specify the Servlet to be read from
jsonData : searchquery, //A JSON Object
params:{
start:0,
limit: itemsPerPage
},
success : function(response) {
mainresponse = response.responseText;
//etc.
}
Is having a separate request redundant?
Could I accomplish this within my store alone (passing my searchquery as a parameter to the server and all that jazz)?
I apologize for this jumbled question in advance!
Cheers
You can use a memory proxy and set the store data with the data property, but I don't recommend that.
If I where you I would forget the ajax request and start take advantage of the store's proxy.
Here's an example
var store = Ext.create('Ext.data.Store', {
storeId: 'resultsetstore',
autoLoad: false,
pageSize: 20,
fields: ['id','name','description'],
proxy: {
type: 'ajax',
url: 'urlToTheServlet', //here I specify the Servlet to be read from
extraParams: {
searchquery: 'Test'
}, //A String Object
reader: {
type: 'json',
root: 'elements'
}
}
});
store.load();
note that the start, limit are dealt with in the background. You don't have to set them manually. You can set a pageSize but it has it's own default, so it's not required.
This is what your data is expected to look like:
{
"elements": [
{
"id": 1,
"name": "John",
"description": "Project Manager"
},
{
"id": 2,
"name": "Marie",
"description": "Developer"
},
{
"id": 3,
"name": "Tom",
"description": "Technical Lead"
}
]
}
UPDATE: Passing an object as payload to the proxy
I had the same issue and I couldn't find an out of the box solution so I wrote my own proxy to resolve this.
Ext.define('BCS.data.proxy.AjaxWithPayload', {
extend: 'Ext.data.proxy.Ajax' ,
alias: 'proxy.ajaxwithpayload',
actionMethods: {
create: "POST",
destroy: "POST",
read: "POST",
update: "POST"
},
buildRequest: function(operation) {
var me = this,
request = me.callParent([operation]);
request.jsonData = me.jsonData;
return request;
}
});
Now you can do this:
var store = Ext.create('Ext.data.Store', {
storeId: 'resultsetstore',
autoLoad: false,
pageSize: 20,
fields: ['id','name','description'],
proxy: {
type: 'ajaxwithpayload',
url: 'urlToTheServlet', //here I specify the Servlet to be read from
jsonData : YOUR_OBJECT
reader: {
type: 'json',
root: 'elements'
}
}
});
I prefer to keep each method in a separated endpoint:
proxy: {
type: 'ajax',
reader: {
type: 'json'
},
api: {
read: 'getCenarioTreeNode', // To request a node children (expand a node)
create: 'createCenarioTreeNode', // When you insert a node
update: 'updateCenarioTreeNode', // When you change a node attribute
destroy: 'destroyCenarioTreeNode' // When you delete a node
},
writer: {
type:'json',
encode:true,
rootProperty:'data'
}
},

Ext.data.LocalStorage not working on Offline Mode

Im now studying Sencha Touch 2 and doing some Research on Ext.data.LocalStorage that can be use in Offline Mode.
I tried to follow this turorial
Sencha Touch 2 Local Storage
and just updated the code from Github - RobK/SenchaTouch2-LocalStorageExample or riyaadmiller/LocalStorage and modified Store url using my own WCF Rest
but i cant get LocalStorage working on offline mode.I have no issue on running the app Online. I also tried to debug it on Chrome developer tool but LocalStorage always get 0 data. I used Chrome/Safari Browser and also build the apps as Android using Phonegap build and still not working.
Did I miss something?
Does anyone can provide the details to deal with this Issue.
Below is my code:
Store:
Ext.define('Local.store.News', {
extend:'Ext.data.Store',
config:{
model: 'Local.model.Online',
proxy:
{
type: 'ajax',
extraParams: { //set your parameters here
LookupType: "Phone",
LookupName: ""
},
url: 'MY WCF REST URL',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
reader:
{
type: 'json'
, totalProperty: "total"
},
writer: { //Use to pass your parameters to WCF
encodeRequest: true,
type: 'json'
}
},
autoLoad: true
}
});
Offline Model:
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});
Online Model:
Ext.define('Local.model.Online', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "Name", type: "string" },
{ name: "Description", type: "string" }
]
}
});
Controller:
Ext.define('Local.controller.Core', {
extend : 'Ext.app.Controller',
config : {
refs : {
newsList : '#newsList'
}
},
/**
* Sencha Touch always calls this function as part of the bootstrap process
*/
init : function () {
var onlineStore = Ext.getStore('News'),
localStore = Ext.create('Ext.data.Store', { storeid: "LocalNews",
model: "Local.model.Offline"
}),
me = this;
localStore.load();
/*
* When app is online, store all the records to HTML5 local storage.
* This will be used as a fallback if app is offline more
*/
onlineStore.on('refresh', function (store, records) {
// Get rid of old records, so store can be repopulated with latest details
localStore.getProxy().clear();
store.each(function(record) {
var rec = {
name : record.data.name + ' (from localStorage)' // in a real app you would not update a real field like this!
};
localStore.add(rec);
localStore.sync();
});
});
/*
* If app is offline a Proxy exception will be thrown. If that happens then use
* the fallback / local stoage store instead
*/
onlineStore.getProxy().on('exception', function () {
me.getNewsList().setStore(localStore); //rebind the view to the local store
localStore.load(); // This causes the "loading" mask to disappear
Ext.Msg.alert('Notice', 'You are in offline mode', Ext.emptyFn); //alert the user that they are in offline mode
});
}
});
View:
Ext.define('Local.view.Main', {
extend : 'Ext.List',
config : {
id : 'newsList',
store : 'News',
disableSelection : false,
itemTpl : Ext.create('Ext.XTemplate',
'{Name}-{Description}'
),
items : {
docked : 'top',
xtype : 'titlebar',
title : 'Local Storage List'
}
}
});
Thanks and Regards
1) First of all when you creating record and adding into store, the record fields should match the model fields of that store.
Here you creating record with field name, but Local.model.Offline didn't name field
var rec = {
name : record.data.name + ' (from localStorage)'
};
This is what you need to do within refresh
localStore.getProxy().clear();
// Also remove all existing records from store before adding
localStore.removeAll();
store.each(function(record) {
console.log(record);
var rec = {
ID : record.data.ID,
LookupName : record.data.Name + ' (from localStorage)',
LookupDescription : record.data.Description
};
localStore.add(rec);
});
// Don't sync every time you add record, sync when you finished adding records
localStore.sync();
2) If specify idProperty in model which is using localStorage, then record will not be added into localStorage.
Model
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
// idProperty removed
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});

ExtJs4 How to assign a model to a store at creation?

I'm defining a store and I want to dynamically assign a Model for it at creation. So if I create my DropDownStore and I don't pass a model config with it it needs to rely on the default model(DropDownModel).
Here is my DropDownModel + DropDownStore:
Ext.define('DropDownModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'Name', type: 'string' }
]
});
Ext.define('DropDownStore', {
extend: Ext.data.Store,
proxy: {
type: 'ajax',
actionMethods: { read: 'POST' },
reader: {
type: 'json',
root: 'data'
}
},
constructor: function(config) {
var me = this;
if (config.listUrl) {
me.proxy.url = config.listUrl;
}
me.model = (config.model) ? config.model : 'DropDownModel'; //This line creates some weird behaviour
me.callParent();
//If the URL is present, load() the store.
if (me.proxy.url) {
me.load();
}
}
});
This is a creation of the DropDownStore with a dynamic model:
Ext.define('RelationModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'RelationName', type: 'string' },
{ name: 'RelationOppositeName', type: 'string' }
]
});
...//a random combobox
store: Ext.create('DropDownStore', {
listUrl: 'someprivateurl',
model: 'RelationModel'
})
...
When I edit the line in the constructor method to
me.model = (config.model) ? config.model : undefined
It works like expected for the dynamic model but not anymore for the default models.
If I let it be
me.model = (config.model) ? config.model : 'DropDownModel';
It works for the default models and not for the dynamic model.
How can I assign a model to a store at creation?
constructor: function(config) {
var me = this;
if (config.listUrl) {
me.proxy.url = config.listUrl;
}
me.callParent();
if (config.extraFields) {
me.model.setFields(config.extraFields);
}
//If the URL is present, load() the store.
if (me.proxy.url) {
me.load();
}
}
store: Ext.create('DropDownStore', {
listUrl: 'someprivateurl',
extraFields: [
{ name: 'Id', type: 'int' },
{ name: 'RelationName', type: 'string' },
{ name: 'RelationOppositeName', type: 'string' }
]
}),

EXTJS 4 Model tries to create a persisted record (instead of update)

Why would a record persisted successfully with a rest proxy calling the POST/Create action, and then on subsequent saves, call the same POST/Create method and not the the PUT/Update one?
POSTS
var ref = beginQuestionnaireControl.getPegfileRef();
var Pegfile = Ext.create('Pegfect.model.Pegfile', {
Id: 0,
Reference: ref
});
Pegfile.save({
scope: this,
success: function (pegfile, operation) {
this.activePegfile = pegfile;
this.startQuestions();
},
failure: function () {
alert('That ref is not unique');
}
});
also POSTS (expecting a PUT)
this.activePegfile.save({
success: function () {
successCallback();
},
failure: function () {
alert('oops, error saving Pegfile');
}
});
proxy
proxy:
{
type: 'rest',
url: 'Pegfile',
timeout: 120000,
noCache: false,
reader:
{
type: 'json',
root: 'data',
successProperty: 'success'
},
writer:
{
type: 'json',
writeAllFields: true
}
}
The trick is to define an 'Id' property on the Model:
idProperty: 'Id'
Crying out for some convention over config on this one...

Resources