PDA

View Full Version : model.save() sends data as json not in the normal format



momesana
12 Aug 2011, 1:51 PM
Hi,
I am trying to save values of a model to the server but the values are send in form of a json object, not in the normal format where parameter names and their values are separated by an equal sign, so it can't be decoded by the server.

that's how my code looks like:




* @classDescription Represents a DoorPlate.
*/
Ext.define('zf.model.DoorPlate', {
extend: 'Ext.data.Model',

fields: [
{name: 'id', type: 'int', mapping: 'OBJ', defaultValue: 0},
{name: 'room', type: 'string', mapping: 'STR_RAUM_NR', defaultValue: ''},
{name: 'roomId', type: 'int', mapping: 'OBJ_RAUM', defaultValue: 0},
{name: 'department', type: 'string', mapping: 'STR_ABTEILUNG', defaultValue: ''},
{name: 'departmentId', type: 'int', mapping: 'OBJ_ABTEILUNG', defaultValue: 0},
{name: 'layoutType', type: 'string', mapping: 'RADIO_LAYOUT', defaultValue: ''},

{name: 'field_0', type: 'string', mapping: 'STR_1_1', defaultValue: ''},
{name: 'fieldId_0', type: 'int', mapping: 'OBJ_1_1', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_1_1', defaultValue: ''},

{name: 'field_1', type: 'string', mapping: 'STR_1_2', defaultValue: ''},
{name: 'fieldId_1', type: 'int', mapping: 'OBJ_1_2', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_1_2', defaultValue: ''},

{name: 'field_2', type: 'string', mapping: 'STR_1_3', defaultValue: ''},
{name: 'fieldId_2', type: 'int', mapping: 'OBJ_1_3', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_1_3', defaultValue: ''},

{name: 'field_3', type: 'string', mapping: 'STR_1_4', defaultValue: ''},
{name: 'fieldId_3', type: 'int', mapping: 'OBJ_1_4', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_1_4', defaultValue: ''},

{name: 'field_4', type: 'string', mapping: 'STR_1_5', defaultValue: ''},
{name: 'fieldId_4', type: 'int', mapping: 'OBJ_1_5', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_1_5', defaultValue: ''},

{name: 'field_5', type: 'string', mapping: 'STR_1_6', defaultValue: ''},
{name: 'fieldId_5', type: 'int', mapping: 'OBJ_1_6', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_1_6', defaultValue: ''},

{name: 'field_6', type: 'string', mapping: 'STR_2_1', defaultValue: ''},
{name: 'fieldId_6', type: 'int', mapping: 'OBJ_2_1', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_2_1', defaultValue: ''},

{name: 'field_7', type: 'string', mapping: 'STR_2_2', defaultValue: ''},
{name: 'fieldId_7', type: 'int', mapping: 'OBJ_2_2', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_2_2', defaultValue: ''},

{name: 'field_8', type: 'string', mapping: 'STR_2_3', defaultValue: ''},
{name: 'fieldId_8', type: 'int', mapping: 'OBJ_2_3', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_2_3', defaultValue: ''},

{name: 'field_9', type: 'string', mapping: 'STR_2_4', defaultValue: ''},
{name: 'fieldId_9', type: 'int', mapping: 'OBJ_2_4', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_2_4', defaultValue: ''},

{name: 'field_10', type: 'string', mapping: 'STR_2_5', defaultValue: ''},
{name: 'fieldId_10', type: 'int', mapping: 'OBJ_2_5', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_2_5', defaultValue: ''},

{name: 'field_11', type: 'string', mapping: 'STR_2_6', defaultValue: ''},
{name: 'fieldId_11', type: 'int', mapping: 'OBJ_2_6', defaultValue: ''},
{name: 'fieldType_0', type: 'string', mapping: 'RADIO_2_6', defaultValue: ''}
],

proxy: {
type: 'ajax',
url : '../fame/wf_nav.gettuerschild',
// keep this parameters from being sent
noCache: false, // Caching is disabled on server side anyway

actionMethods: {
'read' : 'POST'
},

method: 'POST',

reader: {
type: 'json'
},

writer: {
writeAllFields: true,
nameProperty: 'mapping'
}
}
});


Am I doing something wrong?

Thanks in advance

slemmon
12 Aug 2011, 6:41 PM
In your model's proxy what if you set a reader property of encode: true?

*untested

Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email'],


proxy: {
type: 'rest',
url : '/users',
reader: {
type: 'json',
encode: true
}
}
});

skirtle
14 Aug 2011, 5:37 AM
I believe you need two extra settings in your writer:


writer: {
...
encode: true,
root: 'parameterName'
}

where root specifies the name of the request parameter to use to send the JSON.

Documentation here:

http://docs.sencha.com/ext-js/4-0/#/api/Ext.data.writer.Json

momesana
15 Aug 2011, 12:45 AM
That would still pass the parameter as json but it would put it under "<root>" inside the list of parameters. I've checked out the writer source codes and realized there is no such simple writer because that wouldn't make sense in the first place. The data written back to the server is most likely nested and it's most likely an array of data (one entry for each model) because writers are mostly used with stores. It's impossible to effectively send that kind of data to the server without using a mechanism that lets you nest data. Now as a work around I've written a very simple class that does this but it's only supposed to be used with a single model, not stores:



/**
* @classDescription This class is not suitable for anything but a single
* data object supposed to be written to the server. As such it is only
* usable in context of a single model.
*/
Ext.define('zf.StupidSingleWriter', {
extends: 'Ext.data.writer.Writer',

config: {
emptyParam: undefined
},


/**
* Creates new Writer.
* @param {Object} config (optional) Config object.
*/
constructor: function(config) {
Ext.apply(this, config);
},

writeRecords: function(request, data) {
data = data[0];
var key, value;
for (key in data) {
value = data[key];
// Make
request.params[key] = Ext.isEmpty(value) ? emptyParam : Ext.htmlEncode(value);
}

return request;
}
});



Thanks for all your replies :-)