I need a way to get all rendered rows in a treepanel
, but I was not able to find how to achieve it.
I tried the following events:
treepanel#render
: panel.getNodes()
is empty, because the rows get rendered after the panel.treeview#refresh
: it gets called later, and view.up('panel').getNodes()
successfully returns the rowsBut this does not take into account the rows added later by expanding the nodes.
treeview#cellclick
: this could almost work together with treeview#refresh
, but it does not account for programmatically .expand()
a nodetreepanel#itemexpand
: gives access to the expanded node and the row HTMLElement
, but what I need are the children that are renderedI also tried the renderer
in
xtype: 'treepanel',
columns: {
xtype: 'treecolumn',
renderer: function (...)
This is the best candidate in that it is called exactly once for each rendered row, but the problem is that it is called before the row is rendered, so there is no way to get a reference to the rendered row from it.
The same problem applies to gridpanel
, but there things are even more complicated. Among other problems, I was not able to find an event that triggers when a bufferedRenderer
renders new pages of the store.
I was not able to find a solution using the inconsistent events of ExtJs.
Fortunately, in vanilla JS, there is a possibility to get nodes that are inserted to the DOM: MutationObserver
. This is what I came up with:
Ext.define('Mb.Application', {
...
launch: function() {
const body = document.getElementsByTagName('body')[0],
config = { childList: true, subtree: true },
callback = function(mutationsList) {
mutationsList.forEach(mutation => {
if (mutation.type !== 'childList') return
if (!mutation.addedNodes.length) return
mutation.addedNodes.forEach(node => {
// test if it is a row and do what I need
})
})
};
var observer = new MutationObserver(callback.bind(this));
observer.observe(body, config);
I'm not aware of the performance impact this could generate. In my case there was none noticeable.
I don't know if this will help someone, but just in case I share it...