PDA

View Full Version : Constructing nested model from a store and adding to a new store



vick_44
9 Mar 2018, 4:07 AM
To explain better I have created a sample executable code with data.

I have 6 columns of data in a grid as shown below.
57425


On click of a button (in the header) it is supposed to perform below operation,

It should loop through the store records and create a new store which has nested data as below. (I will be describing the store content in a json to explain the representation)
Col4-col6 will be part of a Parent model called 'Company' and Employee model will hold col1-col3 .
Employee will be part of Company model.



{
col4: 'Dunder Miflin',
col5: 'A paper company',
col6: 'The Office',
employees: [{
col1: 'Michael Scott',
col2: '[email protected]',
col3: '555-111-1224'
},{
col1: 'Dwight Schrute',
col2: '[email protected]',
col3: '555-222-1234'
}]
},{
col4: 'Athlead',
col5: 'Sports marketing company',
col6: 'The Office',
employees: [{
col1: 'Jim Halpert',
col2: '[email protected]',
col3: '555-222-4444'
}]
}


The algorithm that I have at the moment is as below
1. create a shallow copy of current store of this grid. (lets call it store1)
2. loop around store1.
3. get the row in the record object. and construct 'Company model' with col4,5,6 values of record object.
4. note down company name, if its same as before then step 2.
5. if company name is different than before then apply filter on store1 for col4 so that I get unique employees under that company name. (that is: if I apply filter on col4 for 'Dunder miflin' I get two rows whereas filter on 'Athlead' will yield 1 row.)
6. loop through this filtered store and construct array (assumption that it would be an array) of 'Employee model' and add to Company model.
7. clear filter on store1.
8. add Company model to its own Company array.
9. end main loop.
10. add the resulting array of Company model to a new store.

The part where I am struggling right now is how do I maintain multiple instances of Employee model objects and assign to parent Company model?. Step 6 mostly.

Below is the executable code I have right now, I am looping through the store and trying to add Employee model to the Company model but when I try to print its contents it doesnt have that data.

Can I please get any pointers as to where I am going wrong. Any help is much appreciated.

copy below code in the embedded fiddle provided at http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.grid.Panel and click preview. Open developer window console and click the header button , it should display
Dunder Miflin
{ some object }
Athlead
{ some object }

But it isnt.
/////////////////////
09:21PM: updated code. shows store contents in lower grid on click of a button on upper grid.
problem seems to be at line company.set('employees',employees);


Ext.define('dataview_model', {
extend : 'Ext.data.Model',
fields : [
{name: 'col1', type: 'string'},
{name: 'col2', type: 'string'},
{name: 'col3', type: 'string'},
{name: 'col4', type: 'string'},
{name: 'col5', type: 'string'},
{name: 'col6', type: 'string'}
]
});

Ext.define('Company', {
extend : 'Ext.data.Model',
fields : [
{name: 'col4', type: 'string'},
{name: 'col5', type: 'string'},
{name: 'col6', type: 'string'},
{name: 'count', type: 'int'}
,{name: 'employees', type: 'Employee'}
]
//,hasMany: [
// {model: 'Employee', name: 'employees'}
//]
});


Ext.define('Employee', {
extend : 'Ext.data.Model',
fields : [
{name: 'col1', type: 'string'},
{name: 'col2', type: 'string'},
{name: 'col3', type: 'string'}
]
});


Ext.create('Ext.data.Store', {
storeId:'myStore',
model: 'Company'
});

Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
model: 'dataview_model',
data:{'items':[
{ 'col1': 'Michael Scott', "col2":"[email protected]", "col3":"555-111-1224" ,
'col4': 'Dunder Miflin', "col5":"A paper company", "col6":"The Office" },

{ 'col1': 'Dwight Schrute', "col2":"[email protected]", "col3":"555-222-1234",
'col4': 'Dunder Miflin', "col5":"A paper company", "col6":"The Office" },

{ 'col1': 'Jim Halpert', "col2":"[email protected]", "col3":"555-222-4444",
'col4': 'Athlead', "col5":"Sports marketing company", "col6":"The Office" }
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
viewId: 'simposons',
selType : 'rowmodel',
header : {
titlePosition: 1,
buttonAlign : 'left',
items : [{
xtype : 'button',
text:'Click me',
itemId: 'exportButton',
listeners: {
click : function(){
var store2 = Ext.data.StoreManager.lookup('myStore');
var store1 = Ext.data.StoreManager.lookup('simpsonsStore');

var companies = [];
var companyName = undefined;
store1.each(function(record){
if(record.data.col4 === companyName){
return true;
}
store1.filter([{
property: "col4",
value: record.data.col4,
exactMatch: true
}]
);
var employees = [];
var counter=0;
store1.each(function(record){
var employeesModel = Ext.create('Employee', record.data);
employees.push(employeesModel);
counter++;
});
console.log('loop counted');
companyName = record.data.col4;
company=Ext.create('Company', record.data);
company.set('employees',employees); //this is where the problem is
company.set('count',counter);
companies.push(company);

store1.clearFilter();
});

store2.add(companies);

store2.each(function(record){
console.log(record.data.col4);
console.log(record.data.employees);
});

}
}
}]
},
columnLines : true,
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{ text: 'col1', dataIndex: 'col1' },
{ text: 'col2', dataIndex: 'col2' },
{ text: 'col3', dataIndex: 'col3' },
{ text: 'col4', dataIndex: 'col4' },
{ text: 'col5', dataIndex: 'col5' },
{ text: 'col6', dataIndex: 'col6' }
],
height: 190,
width: 650,
renderTo: Ext.getBody()
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons2',
selType : 'rowmodel',
columnLines : true,
store: Ext.data.StoreManager.lookup('myStore'),
columns: [
{ text: 'col4', dataIndex: 'col4' },
{ text: 'col5', dataIndex: 'col5' },
{ text: 'col6', dataIndex: 'col6' },
{ text: 'count', dataIndex: 'count' }
],
plugins: [{
ptype: 'rowexpander',
rowBodyTpl: ['<tpl for=".">',

'<tpl if="count &gt; 0">',

'<tpl for="employees">',
'<tr>',
'<td>{col1}</td>',
'</tr>',
'</tpl>',




'</tpl>',

'</tpl>']
}],
height: 150,
width: 450,
renderTo: Ext.getBody()
});

vick_44
9 Mar 2018, 7:41 AM
Here is an updated executable code, the problem is at the below line i believe
company.set('employees',employees);
I dont think this is setting the children employees to the parent company :(
57427

below code shows store contents in bottom grid on click of the button present in top grid header.

copy the code in the embedded fiddle at : http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.grid.Panel





Ext.define('dataview_model', {
extend : 'Ext.data.Model',
fields : [
{name: 'col1', type: 'string'},
{name: 'col2', type: 'string'},
{name: 'col3', type: 'string'},
{name: 'col4', type: 'string'},
{name: 'col5', type: 'string'},
{name: 'col6', type: 'string'}
]
});

Ext.define('Company', {
extend : 'Ext.data.Model',
fields : [
{name: 'col4', type: 'string'},
{name: 'col5', type: 'string'},
{name: 'col6', type: 'string'},
{name: 'count', type: 'int'}
,{name: 'employees', type: 'Employee'}
]
//,hasMany: [
// {model: 'Employee', name: 'employees'}
//]
});

Ext.define('Employee', {
extend : 'Ext.data.Model',
fields : [
{name: 'col1', type: 'string'},
{name: 'col2', type: 'string'},
{name: 'col3', type: 'string'}
]
});

Ext.create('Ext.data.Store', {
storeId:'myStore',
model: 'Company'
});

Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
model: 'dataview_model',
data:{'items':[
{ 'col1': 'Michael Scott', "col2":"[email protected]", "col3":"555-111-1224" ,
'col4': 'Dunder Miflin', "col5":"A paper company", "col6":"The Office" },

{ 'col1': 'Dwight Schrute', "col2":"[email protected]", "col3":"555-222-1234",
'col4': 'Dunder Miflin', "col5":"A paper company", "col6":"The Office" },

{ 'col1': 'Jim Halpert', "col2":"[email protected]", "col3":"555-222-4444",
'col4': 'Athlead', "col5":"Sports marketing company", "col6":"The Office" }
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
viewId: 'simposons',
selType : 'rowmodel',
header : {
titlePosition: 1,
buttonAlign : 'left',
items : [{
xtype : 'button',
text:'Click me',
itemId: 'exportButton',
listeners: {
click : function(){
var store2 = Ext.data.StoreManager.lookup('myStore');
var store1 = Ext.data.StoreManager.lookup('simpsonsStore');

var companies = [];
var companyName = undefined;
store1.each(function(record){
if(record.data.col4 === companyName){
return true;
}
store1.filter([{
property: "col4",
value: record.data.col4,
exactMatch: true
}]
);
var employees = [];
var counter=0;
store1.each(function(record){
var employeesModel = Ext.create('Employee', record.data);
employees.push(employeesModel);
counter++;
});
console.log('loop counted');
companyName = record.data.col4;
company=Ext.create('Company', record.data);
company.set('employees',employees); //this is where the problem is
company.set('count',counter);
companies.push(company);

store1.clearFilter();
});

store2.add(companies);

store2.each(function(record){
console.log(record.data.col4);
console.log(record.data.employees);
});
}
}
}]
},
columnLines : true,
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{ text: 'col1', dataIndex: 'col1' },
{ text: 'col2', dataIndex: 'col2' },
{ text: 'col3', dataIndex: 'col3' },
{ text: 'col4', dataIndex: 'col4' },
{ text: 'col5', dataIndex: 'col5' },
{ text: 'col6', dataIndex: 'col6' }
],
height: 190,
width: 650,
renderTo: Ext.getBody()
});

Ext.create('Ext.grid.Panel', {
title: 'Simpsons2',
selType : 'rowmodel',
columnLines : true,
store: Ext.data.StoreManager.lookup('myStore'),
columns: [
{ text: 'col4', dataIndex: 'col4' },
{ text: 'col5', dataIndex: 'col5' },
{ text: 'col6', dataIndex: 'col6' },
{ text: 'count', dataIndex: 'count' }
],
plugins: [{
ptype: 'rowexpander',
rowBodyTpl: ['<tpl for=".">',

'<tpl if="count &gt; 0">',

'<tpl for="employees">',
'<tr>',
'<td>{col1}</td>',
'</tr>',
'</tpl>',




'</tpl>',

'</tpl>']
}],
height: 150,
width: 450,
renderTo: Ext.getBody()
});

vick_44
16 Mar 2018, 5:59 AM
Finally by trial n error figured how to add array of child model to a parent model.
'Company' model is my parent. hasMany relation with child model 'Employee'

Ext.define('TestUI.model.Company', {
extend : 'Ext.data.Model',
fields : [
{name: 'col4', type: 'string'},
{name: 'col5', type: 'string'},
{name: 'col6', type: 'string'},
{name: 'count', type: 'int'}
]
,hasMany: [
{model: 'TestUI.model.Employee', name: 'employees'}
],
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});

Ext.define('TestUI.model.Employee', {
extend : 'Ext.data.Model',
fields : [
{name: 'col1', type: 'string'},
{name: 'col2', type: 'string'},
{name: 'col3', type: 'string'}
],

proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'employees'
}
}
});



And the magic line is :

company.employees().add(employees);

Pseudo code:

var employees = [];
Loop through records and create employee model and add to employee array: {
var employeesModel = Ext.create('TestUI.model.Employee', record.data);
employees.push(employeesModel);
}
end Loop
//create Company model and add array employees to Company.
var company=Ext.create('TestUI.model.Company', record.data);
company.employees().add(employees);


Other change is I have moved the proxy from store to Company and Employee model.
updated working Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/2efb