PDA

View Full Version : Add new record of Model that contains nested Model



daly
28 Oct 2013, 2:05 AM
What is the best practice for working with Model that contains nested Model?
I will explain my question on simple example.

Guess we have two tables in our DB: Person and City that ont-to-many linked.



Person


id


firstname


city_id




City


id


name








And we have two models and their stores:

Ext.define('City', {
extend : 'Ext.data.Model',
idProperty : 'id',
fields : [ {
name : 'id',
type : 'int'
}, {
name : 'name',
type : 'string'
} ]
});

Ext.define('Person', {
storeId : 'persons',
extend : 'Ext.data.Model',
idProperty : 'id',
fields : [ {
name : 'id',
type : 'int',
useNull : true
}, {
name : 'fullname',
type : 'string'
} ],
associations : [ {
type : 'hasOne',
model : 'City',
associationKey : 'city'
} ]
});

Ext.define('Cities', {
extend : 'Ext.data.Store',
model : 'City',
proxy : {
type : 'rest',
url : '/undi/rest/test/city',
reader : {
type : 'json',
root : 'data'
}
}
});

Ext.define('Persons', {
extend : 'Ext.data.Store',
model : 'Person',
proxy : {
type : 'rest',
url : '/undi/rest/test/person',
reader : {
type : 'json',
root : 'data'
}
}
});



I have simplest task: add, edit and remove Person.


For this purpose, I created grid and window:
Ext.define('PersonWindow', {
extend : 'Ext.window.Window',
autoShow : true,
items : {
xtype : 'form',
frame : true,
items : [ {
xtype : 'textfield',
name : 'fullname',
fieldLabel : 'Full name'
}, {
xtype : 'combobox',
name : 'city',
fieldLabel : 'City',
valueField : 'id',
displayField : 'name',
store : Ext.create('Cities')
} ]
},
buttons : [ {
text : 'Add',
handler : function(button) {

var window = button.up('window');
var form = window.down('form');

// add record
var record = Ext.create('Person', form.getValues());
var grid = Ext.ComponentQuery.query('grid')[0];
var store = grid.getStore();
store.add(record);

window.getEl().mask('Saving...');
store.sync({
success : function() {
window.getEl().unmask();
window.close();
}
});
}
} ]
});

Ext.define('PersonGrid', {
extend : 'Ext.grid.Panel',
renderTo : Ext.getBody(),
autoShow: true,
height : 300,
width : 400,
tbar : [ {
text : 'Add',
handler : function(button, eventObject) {
var window = Ext.create('PersonWindow');
}
} ],
store : Ext.create('Persons'),
columns : [
{
text : 'Full name',
dataIndex : 'fullname'
},
{
text : 'City',
renderer : function(value, metaData, record, rowIndex,
colIndex, store, view) {
return record.getCity().get('name');
}
} ],
listeners : {
afterrender : function(grid, eOpts) {
grid.getStore().load();
}
}
});

Ext.onReady(function() {
Ext.create('PersonGrid');
});


Grid loads the following data:

{
"success": true,
"data": [
{
"id": 1,
"fullname": "Robinson Potter",
"city": {
"id": 11,
"name": "New York"
}
},
{
"id": 2,
"fullname": "Williamson Smith",
"city": {
"id": 12,
"name": "Los Angeles"
}
},
{
"id": 3,
"fullname": "Benson Cooper",
"city": {
"id": 13,
"name": "Chicago"
}
}
]
}

It works fine. The troubles arises when I try to add record to store. It doesn't work.
I want that server receive data as

{
"fullname": "New person name",
"city": {
"id": 15,
"name": "Person city name"
}
}
or

{
"fullname": "New person name",
"city": 15
}

How should I add new record to store?

Scott-1
29 Oct 2013, 4:09 AM
If I understand your question, you are not happy with the format of the JSON that is being sent to the server. If I am wrong then below does not apply. :)

Use a custom writer to do this within the Person Model to pull its association to the city.
http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.writer.Writer

(http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.writer.Writer)

daly
29 Oct 2013, 8:45 AM
Thank very much for your reply. Can you give me a simple example or link?

PS. I wonder why there is no a simple example that shows how to work with form that contains combobox with remote store? I mean how to add and above all how to edit record that loaded into form that contain combobox with remote store (why english is so hard for me :(). Or ExtJS can't do that? I work with framework over two years and can find the example nowhere? I don't understand how other users develop theirs own application as this is simplest task that could be necessary...

Scott-1
29 Oct 2013, 9:57 AM
Here is you sample place this in you model, changing the API crud. Use Fiddler to preview your calls.
,
proxy: {
type: 'rest',
api: {
create : 'Person/create',
read : 'Person/read',
update : 'Person/update',
destroy : 'Person/destroy'
},
writer: {
type: 'json',
writeAllFields: false,
root: 'data',
getRecordData : function (record, operation ){
//return record;
var tmp = ''
tmp = '"fullname" : "John Doe",';
tmp += '"city" : {"id": 15, "name" : "MPLS" }';
return tmp;
}
}
}

As far as other examples, the API has a number of basic examples that could be put together, to form an application.
Databinding to a form look at
http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.form.Panel-method-loadRecord that is the basics of data binding, data binding a multi select combo at this point cannot be done, in the base methods for example, there are others as well.