4.0.* doesn't support the hasOne relationship. 4.1 is meant to support it.
for 4.0.7 I have the following override in place.
Ext.define('HOD.overrides.Form', {}, function() {
/*
* Implementing a nested setValues for forms with
* arrays in them.
*/
Ext.override(Ext.form.Basic, {
setValues: function(values, arrayField) {
var me = this;
function setVal(fieldId, val) {
if (arrayField) {
fieldId = arrayField + '.' + fieldId;
}
var field = me.findField(fieldId);
if (field) {
field.setValue(val);
if (me.trackResetOnLoad) {
field.resetOriginalValue();
}
} else if(Ext.isObject(val)) {
me.setValues(val, fieldId);
}
}
if (Ext.isArray(values)) {
// array of objects
Ext.each(values, function(val) {
setVal(val.id, val.value);
});
} else {
// object hash
Ext.iterate(values, setVal);
}
return this;
},
/**
* Persists the values in this form into the passed {@link Ext.data.Model} object in a beginEdit/endEdit block.
* @param {Ext.data.Model} record The record to edit
* @return {Ext.form.Basic} this
*/
updateRecord: function(record) {
var values = this.getFieldValues(),
name,
obj = {};
function populateObj(record, values) {
var obj = {},
name;
record.fields.each(function(field) {
name = field.name;
if (field.model) {
var nestedValues = {};
var hasValues = false;
for(var v in values) {
if (v.indexOf('.') > 0) {
var parent = v.substr(0, v.indexOf('.'));
if (parent == field.name) {
var key = v.substr(v.indexOf('.') + 1);
nestedValues[key] = values[v];
hasValues = true;
}
}
}
if (hasValues) {
obj[name] = populateObj(Ext.create(field.model), nestedValues);
}
} else if (name in values) {
obj[name] = values[name];
}
});
return obj;
}
obj = populateObj(record, values);
record.beginEdit();
record.set(obj);
record.endEdit();
return this;
}
});
Whats this lets me do is in my forms I create them with names like so.
// Contact details
{
xtype: 'fieldcontainer',
defaultType: 'textfield',
layout: 'anchor',
fieldDefaults: {
anchor: '80%',
allowBlank: true
},
items: [
{
xtype: 'textfield',
name: 'homePhone',
fieldLabel: 'Home phone number'
},
{
xtype: 'textfield',
name: 'mobilePhone',
fieldLabel: 'Mobile phone number'
}]
},
{
xtype: 'fieldcontainer',
defaultType: 'textfield',
layout: 'anchor',
fieldDefaults: {
anchor: '80%',
allowBlank: true
},
items: [
{
name: 'address.id',
xtype: 'hidden'
},
{
name: 'address.building',
fieldLabel: 'Building'
},
{
name: 'address.street',
fieldLabel: 'Street'
},
{
name: 'address.city',
fieldLabel: 'City'
},
{
name: 'address.county',
fieldLabel: 'County'
},
{
name: 'address.postcode',
fieldLabel: 'Postcode'
},
{
name: 'address.country',
fieldLabel: 'Country'
}
]
},
]
Notice the . in the name field which lets the overridden setValues and updateRecord form know it needs to map these values to the new model, which is defined in the model like so.
Ext.define('HOD.model.Employee', {
extend: 'Ext.data.Model',
fields: [
// Person Class
// Auto
'id',
'name',
'homePhone',
'mobilePhone',
{model: 'HOD.model.Address', name: 'address'}, //Address
{model: 'HOD.model.Contact', name: 'iceInformation'} //Person
]
});
Ext.define('HOD.model.Address', {
extend: 'Ext.data.Model',
fields: [
'building',
'street',
'city',
'county',
'postcode',
'country'
],
belongsTo: 'Employee'
});