PDA

View Full Version : [SOLVED] Manipulating a DataView on store update



n3rd
7 Jun 2010, 2:25 AM
Hello,

I'm trying to manipulate the DOM of a DataView created by an XTemplate. The manipulation is currently triggered by the store's update event. However, it seems like at that point in time, the dataview has not yet been re-rendered. As a consequence of that, the manipulations (in my case just a few simple effects) fail.

I can think of a number of hacky ways to get around this, but I was wondering what the best practice is for handling this kind of problem - or did I miss something entirely?

Any thoughts?

Here's the code to reproduce the problem:


var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="dataEl" data-myid="{id}">{id}: {value}</div>',
'</tpl>'
);

var store = new Ext.data.ArrayStore({
autoDestroy: true,
storeId: 'myStore',
idIndex: 0,
data: [
[42, 'Bar', 12], [13, 'Baz', 13.42], [7, 'Boo', -4]
],
fields: [
{name: 'id', type: 'int'},
{name: 'foo', type: 'string'},
{name: 'value', type: 'float'}
]
});

MyPlugin = Ext.extend(Object, {
dataView: null,

constructor: function () {
MyPlugin.superclass.constructor.call(this);
},

init: function (dataView) {
this.dataView = dataView;

this.dataView.getStore().on({
scope: this,
update: this.onStoreUpdate
});
},

onValueChanged: function (record) {
var el = this.dataView.getEl().child('[@data-myid="' + record.get('id') + '"]', true);

// at this point, 'el' references an object that is not in the DOM
console.debug(el);
},

onStoreUpdate: function (store, record, operation) {
if (operation === Ext.data.Record.EDIT && Ext.isDefined(record.modified.value)) {
this.onValueChanged(record);
}
}
});

Ext.onReady(function() {
var dataView = new Ext.DataView({
renderTo: 'content',
tpl: tpl,
itemSelector: '.dataEl',
store: store,
plugins: [new MyPlugin()]
});

// manipulate an element in the store
var record = store.getById(42);
record.beginEdit();
record.set('value', 123.45);
record.set('foo', 'new foo');
record.endEdit();
});

Animal
7 Jun 2010, 2:26 AM
The dataview will refresh itself whenever the Store changes.

n3rd
7 Jun 2010, 2:35 AM
Yes, I know that. However, I want to do some additional stuff from outside the template. For instance, I want to add some effects whenever a numeric value changes based on whether it has gone up or down. And I want to do this without cluttering the XTemplate with <tpl:if>s and such. A DataView-plugin that reacts to the store's update events seemed to be the most logical place for me to do that. Alas, I ran into the problem described above.

Animal
7 Jun 2010, 3:05 AM
Delay the handler call using the delay option.

And then use http://www.extjs.com/deploy/dev/docs/?class=Ext.DataView&member=getNode to get the node from the Record.

n3rd
7 Jun 2010, 4:37 AM
Okay thanks, that does the trick. Although I would still file this approach under "hacky". Simply waiting for a certain intervak hoping that the DOM will be available in time just doesn't feel particularly clean :-/

Animal
7 Jun 2010, 5:24 AM
It's the order in which events are fired. The update event fires before the datachanged event (or whatever event gets fired after update).

Using delay, just means you get the handler function call after.

n3rd
7 Jun 2010, 5:51 AM
Fair enough. I guess it's only half hacky then :)

Thanks a bunch, it's all peachy now.