PDA

View Full Version : [NOREPRO] [ST-2.1.0-RC2] Mapping is not applied to idProperty of the model



KoSik
26 Oct 2012, 5:06 AM
Mapping is not applied to idProperty of the model.


Here is how id field of the model declared:



config: {
idProperty: 'id',
fields: [
{
name: 'id',
mapping: 'taskId',
type: 'int'
}, {
name: 'title',
mapping: 'taskTitle',
type: 'string'
}
]
}




When I try to save non-phantom record (updating) - it sends following request to server:



{"taskTitle":"Test title","id":"169"}




But it should send the following, after applying mapping:



{"taskTitle":"Test title","taskId":"169"}


Problem is inside Writer.js file, where mapping is applied to all properties, except idProperty:



getRecordData: function(record) {
var isPhantom = record.phantom === true,
writeAll = this.getWriteAllFields() || isPhantom,
nameProperty = this.getNameProperty(),
fields = record.getFields(),
data = {},
changes, name, field, key, value;


if (writeAll) {
fields.each(function(field) {
if (field.getPersist()) {
name = field.config[nameProperty] || field.getName();
value = record.get(field.getName());
if (field.getType().type == 'date' && value !== null) {
value = this.writeDate(field, value);
}
data[name] = value;
}
}, this);
} else {
// Only write the changes
changes = record.getChanges();
for (key in changes) {
if (changes.hasOwnProperty(key)) {
field = fields.get(key);
if (field.getPersist()) {
name = field.config[nameProperty] || field.getName();
value = changes[key];
if (field.getType().type == 'date') {
value = this.writeDate(field, value);
}
data[name] = value;
}
}
}
if (!isPhantom) {
// always include the id for non phantoms
data[record.getIdProperty()] = record.getId(); <--- Mapping should be applied to the record.getIdProperty() index
}
}
return data;
}




Of course, it is possible to fix it by defining idProperty: "taskId", but this is not correct, because there is not property called "taskId", it should be "id".

mitchellsimoens
26 Oct 2012, 7:50 AM
I'm not able to reproduce with using store loading or model loading. Here is the test case I used:


Ext.define('MyModel', {
extend : 'Ext.data.Model',

config : {
idProperty : 'id',
fields : [
{
name : 'id',
mapping : 'taskId',
type : 'int'
},
{
name : 'title',
mapping : 'taskTitle',
type : 'string'
}
],
proxy : {
type : 'ajax',
url : 'data/json2.json'
}
}
});


new Ext.data.Store({
autoLoad : true,
model : 'MyModel',
proxy : {
type : 'ajax',
url : 'data/json.json'
},
listeners : {
load : function(store, recs) {
var rec = recs[0];

console.log('Store:');
console.log(rec.getId()); //169
console.log(rec.get('id')); //169
}
}
});

MyModel.load(169, function(rec) {
console.log('Model:');
console.log(rec.getId()); //169
console.log(rec.get('id')); //169
});

data/json.json:


[
{
"taskTitle" : "Test title",
"taskId" : "169"
}
]

data/json2.json:


{
"taskTitle" : "Test title",
"taskId" : "169"
}

KoSik
26 Oct 2012, 8:09 AM
Hi, this is not what I was talking about. Mapping data when you load it works well. Mapping doesn't work for idProperty, when it is updated. Try to modify your example:


MyModel.load(169, function(rec) {
console.log('Model:');
console.log(rec.getId()); //169
console.log(rec.get('id')); //169
rec.set('title', 'My new title');
rec.save();
});

In request to the server you will see the following:

{"taskTitle":"My new title","id":"169"}

But it should be:

{"taskTitle":"My new title","taskId":"169"}

So, problem is NOT in loading data, but in updating.

hawkinbj
19 Nov 2012, 8:37 PM
idProperty also doesn't reflect changes made by function calls within a mapping, i.e. -



Ext.define('mobile.model.Roaster', {
extend : 'Ext.data.Model',
config : {
fields : [ 'thumbnailUrl', 'city', 'country', 'state',
{
name : 'roasterName',
mapping : 'roasterName',
convert : function(v, record) {
return v.indexOf("'") != -1 ? v.replace("'", '&\#39;') : v;
}
}
],
idProperty: 'roasterName'
}
});


roasterName still has raw apostrophe's in the id, but not in the record.data.roasterName. (note: the \ is because the forums will show an apostrophe)