PDA

View Full Version : HasMany relationship and dataGrid



olivierpons
20 Mar 2012, 8:04 AM
Here, you explain how to have a one to many relationship:

http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store (http://docs.sencha.com/ext-js/4-0/#%21/api/Ext.data.Store)

And you get more in detail here:

http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader (http://docs.sencha.com/ext-js/4-0/#%21/api/Ext.data.reader.Reader)

where you explain that "This may be a lot to take in - basically a User has many Orders, each of which is composed of several OrderItems. Finally, each OrderItem has a single Product."
Nice.

Now I want to have a Form where there's the user information PLUS a grid of the user's orders (not the MVC framework, just a a derived class of form.Panel).

How can I do this?

mitchellsimoens
20 Mar 2012, 9:38 AM
You would have to get the store form the hasMany and set that to the grid.

olivierpons
20 Mar 2012, 12:00 PM
Thanks for your answer.

This is what I've done and here's the part of the code that is buggy:


this.gsGrid = new Writer.grid.Panel({
store: this.store,
listeners: {
scope: this,
selectionchange: function(selModel, selected) {
if (selected[0]) {
console.log(selected[0]);
console.log(selected[0].attributs());
this.gsForm.setActiveRecord(selected[0] || null);
this.gsForm.down('#attributsGrid')
.reconfigure( selected[0].attributs() );
}
else {
this.gsForm.setActiveRecord(null);
}
}
}
});


The console.log always works but sometimes, not always, there's an exception raised:


Uncaught TypeError: Cannot read property 'length' of undefined

And the stack is:

Ext.define.onLastFocusChangedext-all-debug.js:65851
Ext.define.setLastFocusedext-all-debug.js:44486
Ext.define.clearSelectionsext-all-debug.js:44556
Ext.define.refreshext-all-debug.js:44544
Ext.define.bindext-all-debug.js:44258
Ext.define.bindStoreext-all-debug.js:45267
Ext.define.bindStoreext-all-debug.js:57707
Ext.define.reconfigureext-all-debug.js:57726
gsGrid.Writer.grid.Panel.listeners.selectionchangeliste.js:411
fireext-all-debug.js:7936
Ext.define.continueFireEventext-all-debug.js:10333
Ext.define.fireEventext-all-debug.js:10318
(anonymous function)ext-all-debug.js:10481
fireext-all-debug.js:7936
Ext.define.continueFireEventext-all-debug.js:10333
Ext.define.fireEventext-all-debug.js:10318
Ext.define.maybeFireSelectionChangeext-all-debug.js:44494
Ext.define.doSingleSelectext-all-debug.js:44479
Ext.define.doSelectext-all-debug.js:44384
Ext.define.selectWithEventext-all-debug.js:44314
Ext.define.onRowMouseDownext-all-debug.js:65818
fireext-all-debug.js:7936
Ext.define.continueFireEventext-all-debug.js:10333
Ext.define.fireEventext-all-debug.js:10318
Ext.define.processUIEventext-all-debug.js:51432
Ext.define.handleEventext-all-debug.js:51379
(anonymous function)
wrap
It only happens when I refresh the page twice (like there's something about cookies or whatever). Tomorrow I'll try to make my code the shortest possible and I'll post the sample, and hope that someone will help me.

olivierpons
21 Mar 2012, 1:54 AM
It seems there's a problem (or bug) with the rendering.

Summary:
- The "main" grid has all its "products" records.
- The "detail" form has its usual fields ("id", "name" and so on), plus a "detail" grid that is supposed to display a list of the attributes of the current product.

Here's how it looks:

32966

In the "selectionchange" event of the "main" grid (i.e. the "produits" grid), I was assigning active record to the form, so that it's "automagically" updated:


this.gsGrid = new Writer.grid.Panel({
store: this.store,
listeners: {
scope: this,
selectionchange: function(selModel, selected) {
this.gsForm.setActiveRecord(selected[0] || null);
}
}
});


Now that I've added a nested grid ("attributes"), I've added this code, so that the nested grid changes its data to the ones of the current record:


this.gsGrid = new Writer.grid.Panel({
store: this.store,
listeners: {
scope: this,
selectionchange: function(selModel, selected) {
if (selected[0]) {
this.gsForm.setActiveRecord(selected[0] || null);
this.gsForm.down('#attributsGrid')
.reconfigure( selected[0].attributs() );
}
else {
this.gsForm.setActiveRecord(null);
}
}
}
});


Here's the declaration of the data models:


Ext.define('Writer.AttributValeur', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int',
useNull: true
},
'description',
'valeur'
],
belongsTo: 'Writer.Produit'
});

Ext.define('Writer.Produit', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int',
useNull: true
},
'titre',
'description',
'prix',
'textDetail',
'imgPetite',
'imgGrande'
]
hasMany: {
model: 'Writer.AttributValeur',
name: 'attributs'
}
});


Everything worked fine until I added the "reconfigure".
If the grid is visible, there's no problem, and a "console.log" trace in the event "selectionchange" shows it's called without any problem:

32967

Now if I let the grid hidden, there's a problem, and an exception is raised:

32968

The detailed error is:

Uncaught TypeError: Cannot read property 'length' of undefined
Ext.define.onLastFocusChanged ext-all-debug.js:65851
Ext.define.setLastFocused ext-all-debug.js:44486
Ext.define.clearSelections ext-all-debug.js:44556
Ext.define.refresh ext-all-debug.js:44544
Ext.define.bind ext-all-debug.js:44258
Ext.define.bindStore ext-all-debug.js:45267
Ext.define.bindStore ext-all-debug.js:57707
Ext.define.reconfigure ext-all-debug.js:57726
gsGrid.Writer.grid.Panel.listeners.selectionchange liste.js:395
fire ext-all-debug.js:7936
Ext.define.continueFireEvent ext-all-debug.js:10333
Ext.define.fireEvent ext-all-debug.js:10318
(anonymous function) ext-all-debug.js:10481
fire ext-all-debug.js:7936
Ext.define.continueFireEvent ext-all-debug.js:10333
Ext.define.fireEvent ext-all-debug.js:10318
Ext.define.maybeFireSelectionChange ext-all-debug.js:44494
Ext.define.doSingleSelect ext-all-debug.js:44479
Ext.define.doSelect ext-all-debug.js:44384
Ext.define.selectWithEvent ext-all-debug.js:44314
Ext.define.onRowMouseDown ext-all-debug.js:65818
fire ext-all-debug.js:7936
Ext.define.continueFireEvent ext-all-debug.js:10333
Ext.define.fireEvent ext-all-debug.js:10318
Ext.define.processUIEvent ext-all-debug.js:51432
Ext.define.handleEvent ext-all-debug.js:51379
(anonymous function)

If you have any idea... I'm stuck.
Sorry to grumble, but I hate this principle: you can do big things with ExtJS, but you're loosing hours and hours and hours and hours and hours with a problem that is unexpected. So all in all, you don't gain time.

olivierpons
22 Mar 2012, 12:30 AM
Like it was 2 years ago, 7 months ago, and now: no answer.

ExtJS is a full mix of DRY and DIY methods :((

So I've given up on this part, I just show the table in the same tab than the rest so there's no update problem (which was absolutely not normal (just removing the first button of the bbar removed the whole form update (when changing record) => sooo strange)).

So now everything works fine, even though it's not the design I wanted. It's still better than anything I will ever be able to do so I shouldn't grumble :D