PDA

View Full Version : [3.2.2] DataView onUpdate fails with exception



Mjollnir26
20 Dec 2010, 5:10 AM
Hello Community,
i think i found a bug in ExtJS once more :-)

I have a setup with a BorderLayout where to the left is a grid which is searchable,
and to the Right there is a DataView which i want to contain ONLY the selected records from the Grid to the left.
This implies that the DataView is bound to the Grid's store.

I did overwrite collectData on the DataView to achieve my desired behaviour (which is working fine so far).
My collectData returns only the Records that are selected in the left grid (the grid in turn refreshes the DataView on selectionchange).

This however leads to an Exception later on as onUpdate incorrectly assumes bufferRender to always return an Ext.query match.



bufferRender : function(records)
{
var div = document.createElement('div');
this.tpl.overwrite(div, this.collectData(records));
return Ext.query(this.itemSelector, div);
},


onUpdate : function(ds, record){
var index = this.store.indexOf(record);
if(index > -1){
var sel = this.isSelected(index);
var original = this.all.elements[index];
var node = this.bufferRender([record], index)[0];

this.all.replaceElement(index, node, true); //FAILS AS NODE is empty!
if(sel){
this.selected.replaceElement(original, node);
this.all.item(index).addClass(this.selectedClass);
}
this.updateIndexes(index, index);
}
},

The behaviour is Browser independent (obviously) and occuring in 3.2.2.
From what i can tell it's in 3.3 as well.

Mjollnir26
20 Dec 2010, 5:20 AM
Ext.override(Ext.DataView,
{
onUpdate : function(ds, record)
{
var index = this.store.indexOf(record);
if(index > -1)
{
var node = this.bufferRender([record], index)[0];

if(! Ext.isEmpty(node))
{
this.all.replaceElement(index, node, true);
var sel = this.isSelected(index);

if(sel)
{
var original = this.all.elements[index];
this.selected.replaceElement(original, node);
this.all.item(index).addClass(this.selectedClass);
}

this.updateIndexes(index, index);
}
}
}
});


P.S. I removed another Mini-Gotcha (the original Variable is only needed once)

Condor
20 Dec 2010, 8:27 AM
You are using DataView for something it isn't meant for.

DataView assumes that every record in the store has a corresponding element in the view, but you break that assumption by not rendering all records.

Can I recommend rendering all records, but modify your tpl, so records that are not selected in the grid are rendered as display:none?

Mjollnir26
20 Dec 2010, 9:07 AM
Condor, i know my type of usage is "a bit off", but why is this assumption made in the first place?

One could earn the DataView quite a bit more flexibillity by filtering out the unneeded stuff at the lowest level (collectData i think)
and simply adding a few security checks here and there.

Esp. the "updateIndexes" method and "onUpdate" need a bit of love here which they are getting by me... :-).

Condor
20 Dec 2010, 9:54 PM
No, I don't think that it will work correctly, even after some extra checks.

What if you have 4 records, records 1, 3 and 4 are selected (so you don't see record 2) and update record 3?

It will try to update index 3, but because record 2 isn't showing, it will update the node for record 4 with the data from record 3!

Mjollnir26
21 Dec 2010, 1:44 AM
Good point but in my DataView Extend (that's what i'm going to build) the lookup for the renderedRecords will be built up based on Record id, not on position in the store.

At least that's my evil plan for now.

But i see where you're coming from and that this behaviour is not a bug at all. I just don't get what collectData should be used for then if not for pre-filtering the DataSet available to the DataView.

Condor
21 Dec 2010, 2:20 AM
I don't see why you would ever override collectData (unless you are creating a subclass like you are planning).

On the other hand, overriding prepareData can be very useful.