I am trying to PUT some data from my frontend (ExtJs) into my backend (Java, Spring). It does not work or I do not get the right clue...
I am on a Ext.grid.Panel where I use the following store which is (nicely) filled and displayed by a this.store.setData( myObject.data.items ) method:
Ext.define( 'NameOfThisClass', {
extend: 'Ext.grid.Panel',
...
store: Ext.create( 'Ext.data.Store', {
data: [],
autoLoad: false,
proxy: {
type: 'rest',
url: '/somepath/theclass',
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'totalCount'
},
writer: {
type: 'json'
},
}
} ),
...
// setting the data to be visualized
setValue: function(myObject) {
this.store.setData( myObject.data.items );
}
...
updateRecord: function(objectId, objectWithUpdateProperties) {
// do what with the store and/or proxy?
}
...
});
I display all entries in a table. The entries are not automatically loaded by the store but set from outside: setValue(myObject).
There is another store for initially loading the data. The data received is then splittet and forwarded in order not to have several requests.
I do get a nice visualized table whose entries are editable by the rowediting plugin.
Ok, so far the backgrounds.
When editing the table's data I run through some validations and gather more data via a modal dialog and then I have the data in order to send to the server by a call of updateRecord(objectId, objectWithUpdateProperties).
This sending is my problem. I do not know how to call/send a rest/put request which will be read by the server. (Receiving is not the problem, sending is).
I guess I somewhat need to trigger my store or the store's proxy. But how?
It is not that I can simply tell my object to save since I do have more data than just the changed object's properties.
Can anyone help me here?
I normally use Ext.Ajax to achieve that, like this:
updateRecord: function(objectId, objectWithUpdateProperties) {
Ext.Ajax.request({
url: 'YourUrl',
params: {
some_param: 'some_value',
object_id: objectId,
object_with_properties_param1: objectWithUpdateProperties.param1
},
success: function(response, opts) {
//Horay, Do something with the response
},
failure: function(response, opts) {
//Oh nooooo
}
});
}
Don't need to use Ajax.
You need to config proxy.api CRUD(C:create, R:read, U:Update. D:Delete) on RestProxy, from client side.
Also, store must have autoSync:true.
At server side, need to config a #RestController for each one of CRUD (with JSON-Java encoder for parameters like Jackson or equivalent), that will acept JSON data. Take into account, that you may send only modified field (store.proxy.writer.writeAllFields: false ->>> default) or just the full record (.writeAllFields:true) to server.
Here an example (inside store's constructor):
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
autoSync: true,
model: 'Test.model.Country',
proxy: {
type: 'rest',
api: {
create: 'country/create',
read: 'counrtry/list'
update: 'counrtry/update',
destroy: 'counrtry/destroy'
},
writer:{
writeAllFields : true
},
reader:{
root:'items',
totalProperty: 'rowCount'
}
}
}, cfg)]);
}
Extra note: For reading from server and load store automatically, just set store.autoLoad: true, and the corresponding #RestController method from server side. Take into account the store.reader params.
Related
I'm new to ExtJS.
I followed a tutorial with the aim to create a pagination on a grid.
The code was simple, and I found it suspicious...
as result, the paging toolbar is there but there are still all the data displayed on the first load.
Here's my code in the View file :
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.GridPanel',
alias: 'widget.userlist',
cls: 'overall',
title: 'xxx <img src="ressource/image/xxx.png" class="title-icon" style= "width: 5%; height: 5%; vertical-align:middle; margin-bottom:0px;" />',
columnLines: true,
dockedItems: [{
xtype: 'pagingtoolbar',
store: 'Users',
pageSize: 2,
dock: 'bottom',
displayInfo: true
}],
I also saw tutorial with a var, but I dont' know where to implement it.
I'm sorry I know there is many tutorials about it out of there but I'm struggling on it :(, I don't mastery JS enough !
Thanks by advance ^_^
edit :
My code in my Store file :
var itemsPerPage = 2;
var store = Ext.define('AM.store.Users', {
pageSize: itemsPerPage,
extend: 'Ext.data.Store',
model: 'AM.model.User',
proxy: {
type: 'ajax',
api: {
read: 'application/data/users.json',
update: 'application/data/updateUsers.json',
},
reader: {
type: 'json',
root: 'users',
idProperty: 'POC',
successProperty: 'success',
totalProperty : 'total'
}
},
autoLoad: false,
});
store.load({
params:{
start:0,
limit: itemsPerPage
}
});
This is telling me : Uncaught TypeError: Object function constructor() { ... has no method 'load'
I tried to remove the store.load, and add {start: 0, limit: 2} after the AutoLoad, according with this http://www.objis.com/formationextjs/lib/extjs-4.0.0/docs/api/Ext.toolbar.Paging.html
With this method, the toolbar shows me " 2-13 data displayed " as it should but there is not data displayed in the grid :'(.
Your server-side stack (PHP, .NET, whatever) will need to be aware of the page, start, and limit parameters that are passed through as part of the request. This is what you'll use to create the proper SQL query (or whatever is being done to retrieve the records) to limit the results to match the paging accommodated by the store.
I'm guessing you're getting all the results because your app server is sending back all the results. The paging provided by ExtJS is really just a handshake with whatever code is running on the server...the paging in a remote store isn't limiting the records, your server-side code is. The AJAX request that the store's proxy sends merely tells the server what it expects to receive back as data.
This is telling me : Uncaught TypeError: Object function constructor()
{ ... has no method 'load'
The reason it is telling you this is because you are trying to invoke the load() method on the 'class' instead of on an instance:
var store = Ext.define('AM.store.Users', {
Ext.define defines a class. To get an instance, you should call Ext.create:
var store = Ext.create('AM.store.Users', { /* ... */ });
This should happen after the 'class' has been defined, but before you invoke the load.
Maybe you should make it a habit to store the result of Ext.define in a variable with a name starting with an uppercase letter, so you can see it represents a class and not an instance:
var Users = Ext.define('AM.store.Users', {
Pagination in a grid requires a buffered store. Something like this
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
// snip
buffered: true,
pageSize: 5
// snip
proxy: {
type: 'ajax',
api: {
read: 'application/data/users.json',
update: 'application/data/updateUsers.json',
},
reader: {
type: 'json',
root: 'users',
idProperty: 'POC',
successProperty: 'success',
totalProperty: 'yourTotalProperty'
}
}
});
Check the outgoing requests (chrome developer tools, firebug or fiddler). If they add page info (page and pageSize) to the Users-requests then your Ext Js code is correct. And of course you also need a web service that supports paging and delivers the requested data chunks.
The below is my MyStore.js:
Ext.define('MyApp.store.MyStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Note',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
/* I want to change the following two filepaths */
read: 'data/notesMar2013.json',
update: 'data/notesMar2013.json'
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
}
});
I am trying to change the read and update values in api of MyStore through controller as follows:
var notesStore = Ext.getStore('MyStore');
notesStore.on('load',function(notesStore){
var proxy = notesStore.getProxy();
Ext.apply(proxy.api,{
/* Changing the file paths here */
read: 'data/notesApr2013.json',
update: 'data/notesApr2013.json'
})
notesStore.load();
},this,{single:false});
//
console.log(notesStore);
By using the above function, I am trying to update MyStore but it is not happening. When I checked in chrome console the values are changed successfully but not updating or overriding the store even I used notesStore.load(). What could be the problem?
I referred the below links
link1
link2
Answer: The code was working fine. Let me explain my problem: I was showing the contents from the store on a container and initially, the container was filled with some content and the height was fixed. If I even add any content to the container then it will become hidden as the container is with fixed height. Till now, the content was being appended to the default content instead of removing the default content and then adding. That was the actual problem.
That should work without any problem, hence you have a error at any other point. Please take a look at the console in this JSFiddle. In here's the test-code I used
Ext.define('MyApp.model.Note',{extend:'Ext.data.Model'});
Ext.define('MyApp.store.MyStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Note',
proxy: {
type: 'ajax',
getUrl: function(request) {
console.log('fetched request url');
console.log(this.api[request.action]);
return request.url || this.api[request.action] || this.url;
},
api: {
/* I want to change the following two filepaths */
read: 'data/notesMar2013.json',
update: 'data/notesMar2013.json'
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
}
});
var store = Ext.create('MyApp.store.MyStore');
console.log('The origin API');
console.log(store.getProxy().api);
store.load();
var proxy = store.getProxy();
var newApi = {read: 'data/2013.json', update: 'data/2013.json' };
Ext.apply(proxy.api,newApi);
console.log('The changed API');
console.log(store.getProxy().api);
store.load();
I created a model which contains a proxy to load a single record and its takes no params. I don't want to use a store since I'll never have more then one record. I create an instance of the Model but can't figure out how to tell it to call and load the record from the server. This is the only example I could find, but I don't have an id to pass.
User.load(123, {
success: function(user) {
console.log("Loaded user 123: " + user.get('name'));
}
});
Also I'm making and ajax call and not a rest call in case that matters.
The load(id, [config]) is static and will return provide you with a new record instance. It uses the proxy that was set via setProxy(proxy) (also static). Per default it will send a read request with the params id: 123. The static method allows you to set some default callbacks within the optional config object. These callbacks are needed to get the instance of the loaded record (or the error).
How it works
// create a Model class
Ext.define('MyApp.User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
]
});
// apply a proxy instance
MyApp.User.setProxy(/*YourAjaxProxy*/);
// prepare a handler
var cb = function(model, op) {
// log the new model instance
console.log(model);
};
// get a instance
MyApp.User.load(123, {
scope: this, // should be the scope of the callback (cb)
success: cb
});
Not what you need? Just comment...
Just make an Ajax request and store the result in a variable.
Ext.Ajax.request({
url: '/data/get',
method: 'GET',
params: {
requestID: 'XXXX',
connName: 'yyyy'
},
success: function (responseData) {
var countResult = Ext.decode(responseData.responseText); }
});
I'm stuck with this code, I'm getting this json formated data from the Youtube API, if I use type:'json' it will fail, because of that cross domain thing but the other elements loads anyway; then, if I change type: to 'jsonp' (which is the syntax described on the ExtJS API) it would give me this error:"Uncaught TypeError: Cannot call method 'substring' of undefined" I tried setting type:'anyotherstupidthing' and the same happens, so what could be happening?
Here are my current data model and my store:
Ext.define('Video', {
extend: 'Ext.data.Model',
fields: ['id', 'title']
});
myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
proxy: {
type: 'ajax',
url : 'http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc',
reader: {
type: 'jsonp',
root: 'items'
}
}
});
Thanks in advance!
Ed.
JsonP requires the server to wrap the returned data in a JS function call. The common contract is to pass a parameter named 'callback' to the server to allow for unique names and avoid name clashes on the client.
Calling the URL http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc&callback=myCallback in the browser shows that YouTube support this convention:
Ext supports JsonP via the Ext.data.proxy.JsonP proxy class. The reader is a standard JSON reader and not JsonP specific, you only need to account for the data structure returned from the server (set root to data.items).
The working code looks like this:
var myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
proxy: {
type: 'jsonp',
url : 'http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc',
reader: {
type: 'json',
root: 'data.items'
}
},
listeners: {
load: function(store, records) {
Ext.each(records, function(rec) {
console.log(rec.get('title'));
});
}
},
autoLoad: true
});
I'm started to use ExtJs4 and have question about ajax proxy. My store looks like this:
var users = new Ext.data.Store({
model: 'User',
autoDestroy: true,
autoSync: true,
autoLoad: true
proxy: new Ext.data.HttpProxy({
type: 'ajax',
api: {
create: '../users.php?action=create',
read: '../users.php',
update: '../users.php?action=update',
destroy: '../users.php?action=delete'
},
reader: {
type: 'json',
root: 'users',
idProperty: 'USRID'
}
}),
});
when I remove some records from this store without page refreshing, it seems that all previous deleted items are stored somewhere and sended to php script on every new update. When I refresh page, first remove is ok, but any next remove again accumulate previous removed records.
What I do wrong and how I can fix it?
You might try:
model.commit();
http://docs.sencha.com/ext-js/4-0/#/api/Ext.data.Model-method-commit
Check the reply you are sending from php page. If you are sending some data that it can't understand as success then it will accumulate previous records. e.g. in Spring make return type void and add attribute #ResponseBody send default ok reply else we need to parse response on client side.