View Full Version : [B2] Extendable TableChunker?

14 Apr 2011, 11:28 AM
I'm trying to create my own TreeView, so that I can add my own classes to the markup (for example, I need to get tree-depth-specific classes onto the rows). I've put a collectData method into my TreeView to put the node's depth onto the record, and all I need to do is get that into the template for the view.

From what I can tell by debugging it, I need my own chunker that I can pass in the config to MyTreeView -> TreeView -> TableView, so that I can define my own metaRowTpl, so that the upstream TableView can construct the template for my items.

Problem is, the only chunker implementation is Ext.view.TableChunker, and it's a singleton. I can't seem to extend the class, as it's a singleton. That would seem to be by design, and it's not a bad one.

(Edit: Seems from other posts, I can extend by using Ext.getClass() on the singleton. Ok, that would seem to work, but isn't that a little bit hacky? (in order to extend a class, I need to drill into its definition to find out if it's declared as a singleton, and then extend or override that way?) Also, I would have to use Ext.extend (Ext.getClass(...)...) instead of Ext.define ({ extend...}), which is less nice.)

In that case, to make my own chunker, I need to copy the whole TableChunker implementation and define my own with the metaRowTpl I need. I clearly prefer not to do that just to get my own metaRowTpl definition inserted into the chain.

I'd like to suggest one of the following as regards Ext.view.TableChunker:

Refactor into an AbstractChunker which the TableChunker singleton extends (and therefore so can I)
Take the singleton property off the TableChunker class (what is the benefit of that here?)
Tell me how I'm doing this wrong ;)

14 Apr 2011, 12:25 PM
I wanted to put a class with the tree node depth on each tree node's row, and limit the depth of the tree, per customer requirement. This is how I solved the problem (note, this is not a fully wired example, obviously):

Ext.define('My.TreeChunker', {
requires: ['Ext.XTemplate'],
metaRowTpl: [
'<tr class="' + Ext.baseCSSPrefix + 'grid-row {addlSelector} {[this.embedRowCls()]} tree-depth-{[this.embedDepth()]}">', // this.embedDepth() defined below
'<tpl for="columns">',
'<td class="' + Ext.baseCSSPrefix + 'grid-cell ' + Ext.baseCSSPrefix + 'grid-cell-{id} {{id}-modified} {{id}-tdCls}" {{id}-tdAttr}><div unselectable="on" class="' + Ext.baseCSSPrefix + 'grid-cell-inner ' + Ext.baseCSSPrefix + 'unselectable" style="{{id}-style}; text-align: {align};">{{id}}</div></td>',
metaTableTpl: [
'<table class="' + Ext.baseCSSPrefix + 'grid-table ' + Ext.baseCSSPrefix + 'grid-table-resizer" border="0" cellspacing="0" cellpadding="0" {[this.embedFullWidth()]}>',
'<tpl for="columns">',
'<th class="' + Ext.baseCSSPrefix + 'grid-col-resizer-{id}" style="width: {width}px; height: 0px;"></th>',
'<tpl for="features">',
'{[this.embedFeature(values, parent, xindex, xcount)]}',
constructor: function () {
Ext.XTemplate.prototype.recurse = function (values, reference) {
return this.apply(reference ? values[reference] : values);

// embed a depth field template value into the template
// (because this template gets created ONCE by running the template,
// and the result is called on each row.)
embedDepth: function (values, parent, x, xcount) {
return '{depth}';
embedFeature: function (values, parent, x, xcount) {
var tpl = '';
if (!values.disabled) {
tpl = values.getFeatureTpl(values, parent, x, xcount);
return tpl;
embedFullWidth: function () {
return 'style="width: {fullWidth}px;"';
openRows: function () {
return '<tpl for="rows">';
closeRows: function () {
return '</tpl>';
embedRowCls: function () {
return '{rowCls}';
openTableWrap: function () {
return '';
closeTableWrap: function () {
return '';
getTableTpl: function (cfg, textOnly) {
var tpl,
tableTplMemberFns = {
openRows: this.openRows,
closeRows: this.closeRows,
embedFeature: this.embedFeature,
embedFullWidth: this.embedFullWidth,
openTableWrap: this.openTableWrap,
closeTableWrap: this.closeTableWrap
tplMemberFns = {},
features = cfg.features || [],
ln = features.length,
i = 0,
memberFns = {
embedDepth: this.embedDepth, // make my function visible to the template
embedRowCls: this.embedRowCls
metaRowTpl = Array.prototype.slice.call(this.metaRowTpl, 0),
for (; i < ln; i++) {
if (!features[i].disabled) {
Ext.apply(memberFns, features[i].getMetaRowTplFragments());
Ext.apply(tplMemberFns, features[i].getTplFragments());
Ext.apply(tableTplMemberFns, features[i].getTableFragments());
metaRowTpl = new Ext.XTemplate(metaRowTpl.join(''), memberFns);
cfg.row = metaRowTpl.applyTemplate(cfg);
metaTableTpl = new Ext.XTemplate(this.metaTableTpl.join(''), tableTplMemberFns);
tpl = metaTableTpl.applyTemplate(cfg);

if (!textOnly) {
tpl = new Ext.XTemplate(tpl, tplMemberFns);
return tpl;

Ext.define('My.TreeView', {
extend: 'Ext.tree.TreeView',
alias: 'widget.mytreeview',
chunker: new My.TreeChunker(), // use my table chunker

collectData: function(records) {
var data = this.callParent(arguments),
rows = data.rows,
ln = rows.length,
for (i = 0; i < ln; i++) {
// set depth on row data to that of tree node
rows[i].depth = records[i].getDepth();

return data;

tree = new Ext.tree.TreePanel(
viewType: 'mytreeview', // specify my treeview extension
border: false,
store: store, // declared elsewhere
singleExpand: true,
draggable: false,
rootVisible: false,
listeners: {
// limit tree depth by making 4th level nodes leaf nodes
'beforeitemappend': function (parent, node) {
if (parent.getDepth() === 3) {
node.data.leaf = true; // only display tree 4 nodes deep (customer requirement)

9 Oct 2011, 8:33 PM
Hi Stevil,

I am also stucked at creating my own markups for my treeview. I tried overriding itemTpl and tpl but to no avail. I am thinking of using ordered list <ul> and nested ordered list for children. I'd also need to use custom fields to display other values on my treeview.

Any help is appreciated. I'm using version 4.0.6.


11 Oct 2011, 2:11 AM
You could try overriding the setNewTemplate function contained in Ext.view.Table. This doesn't seem to be documented though.