How to access Extjs 4 store base properties - extjs

How can I access custom root property from the store like built in properties such as idProperty, totalProperty, messageProperty etc. Please check the code for ref.
Ext.define('app.store.Reviews', {
extend: 'Ext.data.Store',
model: 'app.model.Review',
pageSize: 200,
remoteSort: true,
// allow the grid to interact with the paging scroller by buffering
buffered: true,
proxy: {
type: 'ajax',
url: 'review/list',
reader: {
type: 'array',
root: 'list',
totalProperty: 'count',
myCustomproperty: 'fieldInJson' // Somewhat like this
},
filterParam: 'query'
}
});
update: also I could be able to access the property via store

The jsonData object is available from the proxy.reader. You could access this data in the store load event by adding listener:
Ext.define('app.store.Reviews', {
extend: 'Ext.data.Store',
model: 'app.model.Review',
pageSize: 200,
remoteSort: true,
// allow the grid to interact with the paging scroller by buffering
buffered: true,
proxy: {
type: 'ajax',
url: 'review/list',
reader: {
type: 'array',
root: 'list',
totalProperty: 'count'
},
filterParam: 'query'
},
listeners: {
load: function (store,records,successful,eOpts) {
//older
console.log(store.proxy.reader.jsonData);
//4.2
console.log(store.getProxy().getReader().jsonData);
}
}
});

Related

Extjs 4 grid store MVC with Ext direct url is undefined

I have a grid with store, and I want to load on render or click a button, but when I try to load the grid, got an url is undefined error. I need to use Ext direct, so no url. What should I do?
Ext.define('My.view.Grid' ,{
extend: 'Ext.grid.Panel',
//...
store: 'MyStore',
//...
}
Store:
Ext.define('My.store.MyStore', {
extend: 'Ext.data.JsonStore',
//...
model: 'My.model.MyModel',
proxy: {
type: 'direct',
directFn: Ext.direct.Class.function,
paramOrder: ['start', 'limit', 'sort', 'active'],
reader: {
type: 'json',
root: "data",
idProperty: 'id',
totalProperty: "all"
},
extraParams: {
active: 1
}
},
remoteSort: true,
sorters: ['name']
//...
Extend your store from Ext.data.Store:
Ext.define('My.store.MyStore', {
extend: 'Ext.data.Store',
// ...
});
If you see the source code of Ext.data.JsonStore, you will see that there is predefined an ajax proxy:
constructor: function(config) {
config = Ext.apply({
proxy: {
type : 'ajax',
reader: 'json',
writer: 'json'
}
}, config);
this.callParent([config]);
}

Extjs 4.0.7 paging grid with new proxy

I have a paging grid with a store. I have to change the proxy of the store, but when i do this and try to reload the grid, it gives a loading mask and do nothing else. Can you help me?
This is the original store:
var store = new Ext.data.JsonStore({
autoDestroy: true,
proxy: {
type: 'direct',
directFn: Ext.d.Class.Function,
extraParams: {
param: param
},
paramOrder: ['param', 'filter', 'start', 'limit', 'sort'],
reader: {
type: 'json',
root: "rows",
idProperty: 'id',
totalProperty: "all"
}
},
fields: fields,
remoteSort: true,
autoLoad: false,
sorters: sorters
});
The original grid:
var grid = Ext.create('Ext.grid.Panel', {
selModel: selmodel,
title: title,
flex: 1,
store: store,
columns: columns,
bbar: pager = Ext.create('Ext.PagingToolbar', {
store: store,
displayInfo: true,
displayMsg: '{1} / {2}',
emptyMsg: ""
})
//...
The new proxy:
var newProxy = Ext.create('Ext.data.Proxy', {
type: 'ajax',
paramsAsHash: false,
url: 'tasks.php',
actionMethods: {
read: 'POST'
},
extraParams: {
task: 'getItems',
id: id
},
reader: {
type: 'json',
root: "rows",
idProperty: 'id',
totalProperty: "all"
}
});
And I tried to set proxy and load the store, but it doesn't do anything.
grid.getStore().removeAll();
grid.getStore().setProxy(newProxy);
grid.getDockedItems()[2].store.setProxy(newProxy);
grid.getStore().load(); // fails, loading mask but no ajax
Any idea?
That's because you're not actually creating an Ajax proxy, but its parent class Ext.data.Proxy. The type is not interpreted in these lines:
var newProxy = Ext.create('Ext.data.Proxy', {
type: 'ajax',
You have to specify the actual class name:
var newProxy = Ext.create('Ext.data.proxy.Ajax', {
(And, IMHO, you'd better create it with the new keyword new Ext.data.proxy.Ajax, so that you discover your missing requires early...)

Paging on grid panel (extjs)

I am following the code in the link below to page data on a Ext.grid.Panel without success. Data is rendered altogether in the panel without paging. Apparently, the paging toolbar has no data to display but it is correctly configured to the store that has the data and it is hanging as an item of the grid.
I have copied the exact configurations of store and grid from the example below but nothing happened. Why is the data not being paged?
http://jsfiddle.net/jardalu/TE4ah/
This is my store which is linked to the grid and the paging toolbar:
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
pageSize: 50,
remoteSort: true,
storeId: 'Users',
autoLoad: false,
model: 'AICWeb.model.User',
sortOnLoad: false,
proxy: {
type: 'ajax',
type: 'localstorage',
simpleSortMode: true,
reader: {
type: 'xml'
}
},
sorters: {
property: 'email'
}
}, cfg)]);
}
If you are using localstorage you need to implement the PagingMemoryProxy. This should be the only type on the proxy config, and enable the paging config:
proxy: {
type: 'pagingmemory'
enablePaging: true,
...
}

Extending Ext.data.Store

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
}
});

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

Resources