I'm trying to create a store and inside access the data from another store to construct the proxy url.
Something like this:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData').getAt(0).data.userid,
reader: {
type: 'json'
}
}
}
});
So, I'm basically trying to get the userid from another store to be able to construct the correct url.
This doesn't work, I get:
Uncaught TypeError: Object #<Object> has no method 'getStore'
What is the correct way to do this?
EDIT: Okay I put in a dummy URL and trying to change it with a listener, this is my store now:
Ext.define('MyApp.store.Post',{ extend:'Ext.data.Store',
config: {
fields: [
'title', 'link', 'author', 'contentSnippet', 'content'
],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
listeners: [
{
beforeload: function(){
console.log("store loaded"); //I DON'T SEE THIS IN CONSOLE
return true;
}
}
]
},
});
Basically you did nothing wrong, but the reason is sencha touch uses asynchronous loading and it seems that Ext.getStore() is not instantiated at the time your store is defined.
Let's try this method instead:
First, add a listener for beforeload event inside your store config:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
//url: you don't even need to set url config here, simply ignore it
reader: {
type: 'json'
}
}
},
listeners: [
{
fn: 'setUrl',
event: 'beforeload'
}
]
});
then declare a function like this, in the same file:
setUrl: function(){
this.getProxy().setUrl(Ext.getStore('UserData').getAt(0).data.userid);
return true;
}
This way, it's ensured to set the url for your store's proxy right before it's loaded. And basically at the time, all core methods are instantiated.
Update: please try this with your Post store:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
//autoLoad: true,
fields: ['title', 'link', 'author', 'contentSnippet', 'content'],
proxy: {
type: 'jsonp',
url: 'dummy url',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
},
initialize: function(){
console.log("loaded!");
this.getProxy().setUrl('https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog');
//return true;
}
});
After reading the source code of the pull-to-refresh plugin, I see that Sencha Touch use an Ext.data.Operation instead of Ext.data.Store.load() function. So you will have to put it into the initialize method instead.
Use Ext.data.StoreManager.lookup('UserData') to get the store instance.
But in your case, I would use this somewhere, where you work with the userid:
var postsStoreInstance = ...;
postsStoreInstancegetProxy()._extraParams.userid = userid;
It adds a query paremetry to the store's proxy url
The way you do it is the correct way. What is the code of your store definition?
Make sure your store has storeId: 'UserData'.
See this working example:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id'}
]
});
Ext.create( 'Ext.data.Store', {
model: 'User',
storeId: 'UserData'
});
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData'),
reader: {
type: 'json'
}
}
}
});
Related
I am working with check tree in sencha.
This is my store
Ext.define('crApp.store.modulesStore', {
extend: 'Ext.data.TreeStore',
proxy: {
type: 'memory'
},
model: 'crApp.model.MainTreeModel',
defaultRootProperty: "children",
root: {
expanded: true,
children: [{"text":"Dashboard","moduleId":"1","checked":true,"expanded":true,"children":[{"permission_id":"3","permission_name":"View","text":"Dashboard/View","moduleId":"1_3","checked":false,"leaf":true}]},{"text":"Master","moduleId":"2","checked":true,"expanded":true,"children":[{"text":"Facility","moduleId":"3","checked":true,"expanded":true,"children":[{"permission_id":"1","permission_name":"Create","text":"Facility/Create","moduleId":"3_1","checked":true,"leaf":true},{"permission_id":"2","permission_name":"Edit","text":"Facility/Edit","moduleId":"3_2","checked":true,"leaf":true},{"permission_id":"3","permission_name":"View","text":"Facility/View","moduleId":"3_3","checked":true,"leaf":true},{"permission_id":"4","permission_name":"Delete","text":"Facility/Delete","moduleId":"3_4","checked":true,"leaf":true},{"permission_id":"5","permission_name":"Allocation","text":"Facility/Allocation","moduleId":"3_5","checked":true,"leaf":true}]},{"text":"Marketing","moduleId":"4","checked":true,"expanded":true,"children":[{"permission_id":"1","permission_name":"Create","text":"Marketing/Create","moduleId":"4_1","checked":true,"leaf":true},{"permission_id":"2","permission_name":"Edit","text":"Marketing/Edit","moduleId":"4_2","checked":true,"leaf":true},{"permission_id":"3","permission_name":"View","text":"Marketing/View","moduleId":"4_3","checked":true,"leaf":true},{"permission_id":"4","permission_name":"Delete","text":"Marketing/Delete","moduleId":"4_4","checked":true,"leaf":true}]},{"text":"Department","moduleId":"5","checked":true,"expanded":true,"children":[{"permission_id":"1","permission_name":"Create","text":"Department/Create","moduleId":"5_1","checked":true,"leaf":true},{"permission_id":"2","permission_name":"Edit","text":"Department/Edit","moduleId":"5_2","checked":true,"leaf":true},{"permission_id":"3","permission_name":"View","text":"Department/View","moduleId":"5_3","checked":true,"leaf":true},{"permission_id":"4","permission_name":"Delete","text":"Department/Delete","moduleId":"5_4","checked":true,"leaf":true}]},{"text":"User","moduleId":"6","checked":true,"expanded":true,"children":[{"permission_id":"1","permission_name":"Create","text":"User/Create","moduleId":"6_1","checked":true,"leaf":true},{"permission_id":"2","permission_name":"Edit","text":"User/Edit","moduleId":"6_2","checked":true,"leaf":true},{"permission_id":"3","permission_name":"View","text":"User/View","moduleId":"6_3","checked":true,"leaf":true},{"permission_id":"4","permission_name":"Delete","text":"User/Delete","moduleId":"6_4","checked":true,"leaf":true}]},{"text":"Doctor","moduleId":"7","checked":true,"expanded":true,"children":[{"permission_id":"1","permission_name":"Create","text":"Doctor/Create","moduleId":"7_1","checked":true,"leaf":true},{"permission_id":"2","permission_name":"Edit","text":"Doctor/Edit","moduleId":"7_2","checked":true,"leaf":true},{"permission_id":"3","permission_name":"View","text":"Doctor/View","moduleId":"7_3","checked":true,"leaf":true},{"permission_id":"4","permission_name":"Delete","text":"Doctor/Delete","moduleId":"7_4","checked":true,"leaf":true}]}]}]
}
});
When I use the static data, its working perfectly. The data is coming from php url : http://192.168.1.100:8088/CRApp/yii/web/module/index
How can I set the ajax url in store, so that view can access the data dynamically.
I tried this:
proxy: {
type: 'ajax',
url: 'http://192.168.1.100:8088/CRApp/yii/web/module/tree',
reader: {
type: 'json',
expanded: true,
root: 'children'
}
},
but its not working properly. Any solution?
Ext.define('AppName.store.settings.permissions.GroupPermissionsStore', {
extend: 'Ext.data.TreeStore',
alias: 'store.groupPermissionsStore',
autoLoad: true,
storeId: 'groupPermissionsStore',
load : function (options) {
var successFunction = function (response) {
var grpStore = Ext.data.StoreManager.get('groupPermissionsStore');
var resp = Ext.JSON.decode(response.responseText);
grpStore.setRoot(test);
}
};
//Make ajax call with above function as success function
Ext.Ajax.request({
url: "http://192.168.1.100:8088/CRApp/yii/web/module/index",
cors: true,
async: calltype,
withCredentials: true,
//jsonData: dataPayload,
method: 'POST',
success: successFunction,
failure: function (err) {
//Call back if the ajax call fails
}
});
}
});
Key change for Tree Store is method "setRoot" rather and load data.
For "Ext.data.StoreManager.get('groupPermissionsStore')" to work, the store has be added to stores array in the application's "app.js" file.
I rewrite my working Fiddle from ajax proxy type to memory. I'm trying to load memory store data manually:
// app/model/Employees.js file
Ext.define('Fiddle.model.Employees', {
extend: 'Ext.data.Model',
entityName: 'Employees',
fields: [
{
name: 'profile_pic'
},
{
type: 'int',
name: 'age'
},
{
type: 'string',
name: 'last',
mapping: 'name.last'
},
{
type: 'string',
name: 'first',
mapping: 'name.first'
},
{
type: 'string',
name: 'email'
}
],
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total',
successProperty: ''
}
}
});
// app/store/Employees.js file
Ext.define('Fiddle.store.Employees', {
extend: 'Ext.data.Store',
pageSize: 30, // items per page
alias: 'store.employees',
model: 'Fiddle.model.Employees',
});
//app.js fule - launch() function
var store = Ext.create('Fiddle.store.Employees');
console.log(store);
Ext.Ajax.request({
url: 'mates.json',
success: function(resp) {
var result = resp.responseText;
console.log(result);
// store.loadRawData(result);
store.loadData(result);
console.log(store);
console.log(store.getAt(0));
},
});
As result I have 3386 records in store, every symbol in my json file. And what I see in console as first record:
What I'm doing wrong?
And where I need to put proxy lines - in model or in store?
responseText is a string, which contains the serialized JSON data. You have to deserialize it into an object before you can use loadRawData to load the object through the model converters into the store:
var result = Ext.decode(resp.responseText);
store.loadRawData(result);
loadData and loadRawData differ in that loadData does not call the converters on the model. loadRawData is equivalent to what the ajax proxy does, loadData is not.
Did it in this way:
//in Grid panel js file
listeners: {
afterrender: function(grid, evt) {
var myStore = grid.getStore();
Ext.Ajax.request({
url: 'mates.json',
success: function(resp) {
var result = Ext.decode(resp.responseText);
myStore.getProxy().data = result;
myStore.load();
},
});
}
}
In store autoLoad: true must be disabled. This way of loading instead of store.loadRawData(result); shows the correct number of records in the pagingtoolbar.
Store data is not loading ,when using proxy, but it is working fine with static.
means when I put hard codded data in my store , then it working fine.
my code is like blow...
model
Ext.define('new_app.model.BlogModel', {
extend : 'Ext.data.Model',
config : {
fields: [{
name: "firstName",
type: "string"
},{
name:"lastName",
type:"string"
}]
}
});
Store
Ext.define('new_app.store.blogs',{
extend:'Ext.data.Store',
config:{
model: "new_app.model.BlogModel",
proxy: {
type: 'ajax',
url: "data/testStore.js",
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true
}
});
And my view
Ext.define('new_app.view.Blog',{
extend:'Ext.navigation.View',
xtype:'blog',
requires:[
"Ext.dataview.List"
],
config: {
title:'Blog',
iconCls:'star',
items:[{
xtype:'list',
itemTpl: '<div class="contact">{firstName} <strong>{lastName}</strong></div>',
title:'Recent Posts',
store:'blogs'
}]
},
initialize: function(){
this.callParent();
// var storeData = Ext.widget('myblogs');
// console.log(storeData);
// this.setData(storeData);
}
});
Please help me.
It all looks good except that proxy/reader should be preferably configured on model, not on store. Now, how to debugg the thing:
Verify that there a request sent to the server (store is autoLoad so it should)
Verify that a valid json comes back
See if rootProperty matches that what comes in json
BTW, this looks like Sencha Touch, right?
I need to read content from a data source which is located on a remote server(I do not have access to modify anything)
I have tried days to get the content , but doesn't work.
What then I did was I downloaded this data source which is a xml file and put it under same folder with my code to test the correctness of my code syntax and found that the code works.
But when I changed back to the external data resource(
from: url: 'app/store/configuration.xml'
to : url: 'http://webtrak.bksv.com/mel/configuration'
), it still reads but returns no content.
This is not caused by CORS issue as I am testing my app on real devices.
Here are my store and model. Please help
Ext.define('myApp.store.SensorStationStore', {
extend: 'Ext.data.Store',
requires: ['myApp.model.SensorStation', 'Ext.data.reader.Xml'],
config:{
model: 'myApp.model.SensorStation',
storeId: 'SensorStore',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'http://webtrak.bksv.com/mel/configuration',
//url: 'app/store/configuration.xml',
reader: {
type: 'xml',
record: 'locations',
rootProperty: 'nmts'
}
}
}
});
Ext.define('myApp.model.SensorStation', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'name',
type: 'string',
mapping: '#name'
//convert: function (value, record) {
// Ext.Msg.alert(value,record.raw);
// //var nodes = rec.raw.querySelectorAll('');
//}
},
{
name: 'lat',
mapping: '#latitude',
type: 'float'
},
{
name: 'lng',
mapping: '#longitude',
type: 'float'
},
{
name: 'locid',
mapping:'#locid',
type: 'string'
}
]
}
});
Thank you.
I figured out what's the problem is... I have never worked with XML so,I don't know how the response of ajax request look like ,but by applying following code for store will fill your app's store(just a little change in your code)
Code:
Ext.define('myApp.store.SensorStationStore', {
extend: 'Ext.data.Store',
requires: ['myApp.model.SensorStation', 'Ext.data.reader.Xml'],
config:{
model: 'myApp.model.SensorStation',
storeId: 'SensorStore',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'http://webtrak.bksv.com/mel/configuration',
//url: 'app/store/configuration.xml',
reader: {
type: 'xml',
record: 'locations',
rootProperty: 'nmts'
}
}
} });
You are trying to apply store configs outside of config object. Cheers!!
I am trying to centralize my configuration of EXTJS stores within my application, however, I cannot seem to figure out how to make this happen. I am using ExtJS 4.1.
I have a base store, which I want to hold all of the repetitive configuration stuff, and then my more specific stores to hold what's actually different.
Ext.define('My.store.Abstract', {
extend: 'Ext.data.Store',
autoload:false,
proxy: {
type: 'ajax',
reader: {
type: 'json',
root: 'data',
totalProperty: 'total',
successProperty: 'success',
messageProperty: 'message'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data',
allowSingle: false
},
simpleSortMode: true
}
});
Then I would like to provide the store specific stuff on a store by store basis --
Ext.define('My.store.Products', {
extend: 'My.store.Abstract',
storeId: 'Products',
model: 'My.model.Product',
proxy: {
api: {
create: '/myurl/create',
read: '/myurl/index',
update: '/myurl/update',
destroy: '/myurl/delete'
}
}
});
What I am finding is that it just doesnt behave at all. I believe it has something to do with the proxy, but I just can't track it down.
What is the correct way to do this? I would prefer not to replicate the same configuration stuff (from my abstract store) across the 350+ stores in my application. As of now, that it what I have, and I thought I was trying to implement a pretty basic concept .. to no avail.
I know things are not working, as basic as the pageSize, or even the autoLoad .. because they are not being respected at all.
I've played around with constructors, and calling the parent.
Any help would be greatly appreciated.
You can't do it that way because you're expecting to to merge the objects which it just won't do.
Instead, you'll want to look at something like this (untested):
Ext.define('Base', {
extend: 'Ext.data.Store',
autoLoad: false,
constructor: function(config) {
// applyIf means only copy if it doesn't exist
Ext.applyIf(config, {
proxy: this.createProxy()
});
this.callParent([config]);
},
createProxy: function() {
return {
reader: {
type: 'json',
root: 'data',
totalProperty: 'total',
successProperty: 'success',
messageProperty: 'message'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data',
allowSingle: false
},
simpleSortMode: true
}
}
});
Ext.define('Sub', {
extend: 'Base',
createProxy: function(){
var proxy = this.callParent();
proxy.api = {
create: 'create',
update: 'update'
};
return proxy;
}
});
Here is another way:
Base store (app/store/Base.js):
Ext.define('Admin3.store.Base', {
extend: 'Ext.data.Store',
autoLoad: true,
autoSync: true
});
Base proxy (app/proxy/Base.js):
Ext.define('Admin3.proxy.Base', {
extend: 'Ext.data.proxy.Ajax',
alias: 'proxy.base',
reader: {
type: 'json',
root: 'items',
successProperty: 'success',
messageProperty: 'message'
},
listeners: {
exception: function(proxy, response, operation){
console.log(response, operation);
Ext.Msg.show({
title: 'Remote Exception',
msg: typeof operation.getError() === 'string' ? operation.getError() : operation.getError().statusText,
icon: Ext.Msg.ERROR,
buttons: Ext.Msg.OK
});
}
}
});
Concrete store (app/store/Users.js):
Ext.define('Admin3.store.Users', {
extend: 'Admin3.store.Base',
model: 'Admin3.model.User',
proxy: Ext.create('Admin3.proxy.Base', {
api: {
read: 'data/read.php',
update: 'data/update.php'
}
})
});
I think the other answers here might be a bit more complicated than they need to be. As of version 4.0.0, ExtJS has an Ext.Object.merge() method that will allow an approach very close to what the asker was attempting.
Using the values that the asker has, I'd define my "abstract" store like this:
Ext.define("Ext.ux.data.Store", {
extend: "Ext.data.Store",
constructor: function(config) {
var defaults = {
autoload: false,
proxy: {
type: "ajax",
reader: {
type: "json",
root: "data",
totalProperty: "total",
successProperty: "success",
messageProperty: "message"
},
writer: {
type: "json",
encode: true,
writeAllFields: true,
root: "data",
allowSingle: false
},
simpleSortMode: true
}
};
this.callParent([Ext.Object.merge({}, defaults, config)]);
}
});
I'd then create my concrete stores like this:
Ext.create("Ext.ux.data.Store", {
storeId: "ExampleStore",
model: "ExampleModel",
autoLoad: true, // This overrides the defaults
proxy: {
api: {
read: "/example/read" // This overrides the defaults
}
}
});
This approach will also work for multiple levels of components. You could, for instance, model a read-only store:
Ext.define("Ext.ux.data.ReadonlyStore", {
extend: "Ext.ux.data.Store",
constructor: function(config) {
var overrides = {
proxy: {
api: {
create: undefined,
update: undefined,
destroy: undefined
}
}
}
this.callParent([Ext.Object.merge({}, config, overrides)]); // Note that the order of parameters changes here
}
});