ExtJS6 model is not forming correct proxy urls for dynamic parameters
Model looks like
Ext.define('Testt.model.User', {
extend: 'Ext.data.Model',
fields: ['id', 'name'],
proxy: {
type: 'ajax',
api : {
read : 'api/user/:id',
create : 'api/user',
update : 'api/user/:id',
destroy : 'api/user/:id'
},
reader : {
type : 'json'
},
writer : {
type : 'json'
}
}
});
Now when called to load a user record like
Testt.model.load(27, { success: function(rec){console.log(rec)}})
It does not replace :id with actual 27
If you use the REST Proxy type (http://docs.sencha.com/extjs/6.0.1-classic/Ext.data.proxy.Rest.html) then the IDs will be automatically appended to your URLs. You don't need the ':id' syntax in the urls.
Check out this fiddle to see it working: https://fiddle.sencha.com/#fiddle/1cri
Related
is it possible to parse json response without root object in extjs4.1.If yes can anybody tell how to do
Thanks
For this, you need to not define the root (reader property of proxy). For example, when you have root and total property, the proxy definition looks like the following
proxy: {
type: "ajax",
url: "users.json",
reader: {
type : 'json',
root : 'result.account',
totalProperty: "result.totalRecords"
}
}
Without the root (that means there is no totalProperty as well), the definition will look like this
proxy: {
type: "ajax",
url: "users.json",
reader: {
type : 'json'
}
}
I am working in extjs4 MVC.I am going to stuck at a point where I am going to set dynamically proxy type to 'localstorage' where I am replacing my proxy type which is 'ajax' which is declared in model class.
When I want to store data at client side for that I am changing my model proxy type from ajax to locastorage.but when I am calling save() method on particular model object that data are going to server side not saved at client side.Plese give me some suggestion
1) Here is my model data class
Ext.define('Am.model.sn.UserModel',{
extend: 'Ext.data.Model',
fields: ['userId','firstName','middleName','lastName','languageId','primaryEmail','birthDate','password','securityQuestionId','securityQuestionAnswer','isMale','creationTime','ipAddress','confirmationCode','userStatusId',],
proxy:
{
type:'ajax',
api:
{
read:'index.php/SocialNetworking/user/AuthenticateLogin',
create:'index.php/SocialNetworking/user/AuthenticateLogin',
},//end of api
reader:
{
type:'json',
},//end of reader
writer:
{
type:'json',
root:'records',
},//End of writer
}//end of proxy
});
2) here is my some controller file code
Ext.define('Am.controller.sn.UserController',
{
extend:'Ext.app.Controller',
stores:['sn.UserStore','sn.SecurityquestionStore'],
models:['sn.UserModel','sn.SecurityquestionModel'],
views:['sn.user.Login','sn.user.Registration','sn.user.ForgetMyKey','sn.user.SecurityQuestion','sn.user.KpLogin'],
-----
----
init:function()
{
--------
}
remeberMe:function()
{
console.log("check box selected");
var email=this.getUserName().getValue();
var password=this.getPassword().getValue();
var objCheckBox=Ext.getCmp('checkbox');
if(objCheckBox.getValue()==true)
{
window.localStorage.clear();
//code for stoaring data at local storage
var modelObject = Ext.ModelManager.create(
{
primaryEmail:email,
password: password,
}, 'Balaee.model.sn.UserModel');
proxy=modelObject.getProxy();
//proxy=modelObject.getProxy();
proxy.type='localstorage';
//proxy.set(type,'localstorage');
proxy.id='rememberMe';
//proxy.set(id,'rememberMe');
//modelObject.setProxy(proxy);
//console.log("models proxyyyyyyyyyy="+modelObject.getProxy().type+""+modelObject.getProxy().id);
modelObject.setProxy(proxy);
//
I am also trying this but not work
//Ext.apply(proxy,{type:'localstorage',id:'remember' });
modelObject.save();
// code to hide login window
//var obj=Ext.ComponentQuery.query('#loginId');
//console.log("Object name = "+obj[0].id);
//obj[0].hide();
}//end of if statement
else
{
console.log("check box is not selected");
}//end of else statement
},//End of rememberMe function
});
please give me some suggestion.....
I created a sample code for a better understanding of switching proxxies.
//Defining model
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [{name: 'name', type: 'string'}]
});
//creation of ajax proxy
var ajaxProxy = new Ext.data.proxy.Ajax({
id: 'ajaxp',
reader: 'json'
});
//creation of local storage proxy
var lsProxy = new Ext.data.proxy.LocalStorage({
id: 'localp',
reader: 'json'
});
//Create instance of model
var user = Ext.create('User', {
name : 'Pravin Mane',
proxy: ajaxProxy //sets the ajax proxy
});
//Somewhere in your code
user.setProxy(lsProxy); //sets the localstorage proxy
You can set the proxy using the method setProxy(), defined on the Ext.data.Model.
I am trying to reuse a store by altering proxy url (actual endpoint rather than params). Is it possible to override proxy URL for a store instance wih the following syntax:
{
...some view config ...
store: Ext.create('MyApp.store.MyTasks',{proxy:{url:'task/my.json'}}),
}
if proxy is already well defined on the Store definition?
EDIT: AbstractStore source code sets proxy the following way
if (Ext.isString(proxy)) {
proxy = {
type: proxy
};
}
SOLUTION : store.getProxy().url = 'task/myMethod.json';
{
... some tab config ...
store: Ext.create('MyApp.store.MyTasks'),
listeners: {
afterrender: function(tab) {
tab.store.getProxy().url = 'task/myMethod.json'; //<--Saki magic :)
tab.store.load();
}
}
}
http://www.sencha.com/forum/showthread.php?149809-Reusing-Store-by-changing-Proxy-URL
You cannot override the url of a proxy alone when creating a store. You will have to pass a complete proxy. This is because, the library replaces the proxy as a whole! So, what you can do is:
{
...some view config ...
store: Ext.create('MyApp.store.MyTasks',{
proxy: {
type: 'ajax',
url : 'task/my.json',
reader: {
type: 'json',
root: 'rows'
}
}
}),
}
Now another possibility is, changing the end point after you have the instance of store. If you need to load the store from a different endpoint, you can make use of the load method.
store.load({url:'task/others.json'});
Since, in your case you are trying to re-use a store, you can pass the whole proxy. Your store's (MyApp.store.MyTasks) constructor should be capable of handling the new config and applying it to the store... Here is an example:
constructor: function(config) {
this.initConfig(config);
this.callParent();
}
Use the store.setProxy() method. Link here:
I have a BaseStore which I use to store default settings.
Ext.define('ATCOM.store.Shifts', {
extend : 'ATCOM.store.BaseStore',
model : 'ATCOM.model.Shift',
constructor : function(config) {
this.callParent([config]);
this.proxy.api = {
create : 'shifts/create.json',
read : 'shifts/read.json',
update : 'shifts/update.json',
destroy : 'shifts/delete.json',
};
}
});
I'm building some models to interact with an existing API from a previous project.
The API relies on standard POST methods to save the data.
I've configured a model and proxy up to the point where it does push the data onto the server but there only seems to be two writer types, json & xml.
proxy: {
/* ... */
reader: {
type: 'json',
root: 'results'
},
writer: {
type: '???' // <-- can only see json or xml in the docs
}
}
Isn't there a standard POST writer that simply submits data in post fields?
I'm surprised that wouldn't be a standard writer type.
(Parsing the json format wouldn't be too hard to implement but that would mean updating a lot of the old api files.)
Ok, I was able to create that writer quite easily by checking the existing writers' source code.
One thing those existing writers are able to do - and that may be why the dev team only implemented a json and xml version - is that they can push multiple records at once.
That could be implemented in POST but would be a bit more complicated.
This writer will work if you're trying to push a single model to an api using POST:
Ext.define('Ext.data.writer.SinglePost', {
extend: 'Ext.data.writer.Writer',
alternateClassName: 'Ext.data.SinglePostWriter',
alias: 'writer.singlepost',
writeRecords: function(request, data) {
request.params = data[0];
return request;
}
});
and the use this for the writer in the proxy:
writer: {
type: 'singlepost'
}
Based on Ben answer I've implemented my own writer that will collect all properties of all models into arrays.
For example if you have model like with some fields:
fields:[
{name:'id', type:'int'}
{name:'name', type:'string'}
{name:'age', type:'date'}
]
A request string will be
id=1&id=2&id=...&name=oleks&name=max&name=...&age=...
Code:
Ext.define('Ext.data.writer.SinglePost', {
extend: 'Ext.data.writer.Writer',
alternateClassName: 'Ext.data.SinglePostWriter',
alias: 'writer.singlepost',
writeRecords: function(request, data) {
if(data && data[0]){
var keys = [];
for(var key in data[0]){
keys.push(key);
}
for(var i=0;i<keys.length;i++){
request.params[keys[i]] = [];
for(var j=0;j<data.length;j++){
request.params[keys[i]].push((data[j])[keys[i]]);
}
}
}
return request;
}
});
For Sencha touch 2.0, change the writeRecords method to:
writeRecords: function (request, data) {
var params = request.getParams() || {};
Ext.apply(params, data[0]);
request.setParams(params);
return request;
}
Here's my version, adapted from answers above:
// Subclass the original XmlWriter
Ext.define('MyApp.utils.data.writer.XmlInAPostParameter', {
extend : 'Ext.data.writer.Xml',
// give it an alias to use in writer 'type' property
alias : 'writer.xml_in_a_post_parameter',
// override the original method
writeRecords : function(request, data) {
// call the overriden method - it will put the data that I
// want into request.xmlData
this.callParent(arguments);
// copy the data in request.xmlData. In this case the XML
// data will always be in the parameter called 'XML'
Ext.apply(request.params, {
XML: request.xmlData
});
// Already copied the request payload and will not send it,
// so we delete it from the request
delete request.xmlData;
// return the modified request object
return request;
}
});
Ext.define("MyApp.model.MyModel", {
extend : "Ext.data.Model",
requires : [
'MyApp.utils.data.writer.XmlInAPostParameter'
],
fields : [ 'field_A', 'field_B' ],
proxy : {
type : 'ajax',
api : {
read : '/mymodel/read.whatever',
update : '/mymodel/write.whatever'
},
reader : {
type : 'xml'
},
writer : {
// use the alias we registered before
type : 'xml_in_a_post_parameter'
}
}
});
i'm very new to extjs and i'm trying to make some sense of from what i know from Jquery. I want to have an object to be used application wide as key=>val. I think that using a store is the way to go about it but i can't get it to post any parameters. I have tried dozens of variations to call it but no luck. The code i'm using for now is
var store = new Ext.data.JsonStore({
proxy: new Ext.data.HttpProxy({
method: 'POST' ,
url: '/LoadLanguage.html',
}),
autoload: true,
baseParams: {
'code' : code
},
root: '',
fields: [{name: 'Time', mapping: 'Time', type: 'int'}]
});
Problem is that the $_POST variable is always empty and the GET is like http://lordos.home.local/LoadLanguage.html?_dc=1305874986764&page=1&start=0&limit=25
I need it to post the parameters cause GET will not do.
Thanx
I'm trying to understand what you're doing to please forgive me if this is just not going to work for you.
If you want to have a key=>val storage mechenisim I would suggest the KISS method and use a literal JS object to store / get the data.
// Define a namespace.
window.MyNamespace = {};
// Add my config object to hold key => balue
MyNamespace.config = {};
MyNamespace.config = {
key : 'value',
key2 : 'value2'
};
Do do an ajax request I would use...
Ext.Ajax.Request({
method:'POST', // This is the default value, here for you to see.
url:'/LoadLanguage.html',
params: {
'post_key1' : 'post_value1',
'post_key2' : 'post_value2'
},
success:function(response) {
var text = response.responseText;
MyNamespace.config.language = text;
}
});