PDA

View Full Version : Problem with Ext.override in 4.1



LisburnLad
3 Jan 2012, 1:43 PM
In version 4.0x I was using the Ext.override method to override the Ext.tree.Column class, to allow me to add a background-position style attribute to tree nodes. Using this I was then able to supply the position of an icon in an image sprite, in the record for each tree node. However, the behaviour of Ext.override seems to have changed in version 4.1 (I'm currently using the latest beta) and now, rather than overriding the class, both classes seem to be used. The result of this is that my tree now appears twice - once from the original Ext.tree.Column class and once from my override class.

My override is composed by taking the whole of Column.js (from src\tree) and wrapping it as follows:



Ext.require('Ext.tree.Column', function ()
{
Ext.override(Ext.tree.Column,
{
initComponent: function ()
{
var origRenderer = this.renderer || this.defaultRenderer,
origScope = this.scope || window;

this.renderer = function (value, metaData, record, rowIdx, colIdx,store,view)
{
var buf = [],
format = Ext.String.format,
depth = record.getDepth(),
treePrefix = Ext.baseCSSPrefix + 'tree-',
elbowPrefix = treePrefix + 'elbow-',
expanderCls = treePrefix + 'expander',
imgText = '<img style="background-position:{2};" src="{1}" class="{0}" />',
checkboxText = '<input type="button" role="checkbox" class="{0}" {1} />',
formattedValue = origRenderer.apply(origScope, arguments),
href = record.get('href'),
target = record.get('hrefTarget'),
cls = record.get('cls');


while (record)
{
if (!record.isRoot() || (record.isRoot() && view.rootVisible))
{
if (record.getDepth() === depth)
{
buf.unshift(format(imgText,
treePrefix + 'icon ' +
treePrefix+'icon' +(record.get('icon') ? '-inline ':(record.isLeaf() ? '-leaf ' : '-parent ')) +
(record.get('iconCls') || ''),
record.get('icon') || Ext.BLANK_IMAGE_URL,
record.get('iconPos') || '-1px -1px'
));


....
CONTINUES AS EXACT COPY FROM tree\Column.js
....



The parts of the code shown in red are the additions I've made to the class, to allow the location of the icon in the sprite to be set.

In version 4.0x all of this worked fine - a single tree was drawn and the icon specified by the position in the sprite was added as the tree node icon.

Now, in version 4.1, when the tree is being drawn, for some reason the original Ext.tree.Column class is called. This creates the nodes for the tree without the background-position attribute. However, when it reaches the line equivalent to the line shown in green above, it then calls the 'renderer' function in the override class and at this point my code gets run. This results in my markup for the tree icons being loaded into 'formattedValue', which is normally used to supply the tree node's text, and so 2 icons appear for each tree node. The result of this is shown in the attached image. The parts of the tree on the left come from the original class and those on the right from the overriding class.

30434


Would anyone know why this behaviour is now happening in version 4.1 (does it represent a bug in the Ext.override function?) or of any possible work-arounds, or altenative methods I could use to set the background position for the sprite into the tree node markup.

Thanks for any help.

Regards,
Steve

mitchellsimoens
4 Jan 2012, 7:38 AM
The preferred method is using Ext.define:


Ext.define('Override.tree.Column', {
override : 'Ext.tree.Column',

initComponent: function() {....}
});

This allows it to be stripped out to it's own file and dynamically loaded as you just need to require the class name and the override will be applied. I usually create a folder in the root of my app named 'overrides' and then add the path to Ext.Loader:


Ext.Loader.setConfig({
enabled : true,
paths : {
Override : 'overrides'
}
});

If you ever want to call the class that you are overriding you can do that via this.callOverridden(arguments) just like you use this.callParent(arguments);

LisburnLad
4 Jan 2012, 1:44 PM
Hi Mitchell,

Thanks for your reply - although I'm afraid it didn't fix my problem. I am definitely moving towards the opinion that the problem is caused by a bug in version 4.1.

I've simplified things down to the following:



<!DOCTYPE html />
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Tree Test</title>
<link rel="stylesheet" type="text/css" href="Lib/ExtJS/resources/css/ext-all.css"/>
<script type="text/javascript" src="Lib/ExtJS/ext-all-debug.js"></script>
<script type="text/javascript">

Ext.onReady(function ()
{
Ext.tree.Column.override(
{
initComponent: function ()
{
this.renderer = function (value, metaData, record, rowIdx, colIdx, store, view)
{
return 'Hello';
}
this.callParent(arguments);
}
});

var tree = Ext.create('Ext.tree.TreePanel',
{
renderTo: Ext.getBody(),
width: 200,
height: 200,
expanded: true,
root: {
text: 'Tree 1',
children: [
{ text: '01', leaf: true },
{ text: '02', leaf: true },
{ text: '03', leaf: true },
{ text: '04', leaf: true },
{ text: '05', leaf: true}]
}
})
});

</script>
</head>
<body/>
</html>



In version 4.0.7 this produces a single tree composed entirely of the text 'Hello' i.e. all the rendering is being performed by the overriding class as expected and no node icons are drawn since the overriding class no longer contains this functionality:

30456

However, when version 4.1 Beta is used, the override class seems to only be used to provide the node text - therefore all the node icons still appear, even though the functionality to render these should now have been hidden by the overriding class.

30457

Additionally, when I put a break point on the 'initComponent' function of Ext.tree.Column in ext-all-debug.js, this gets hit in version 4.1, but not in 4.0x, prooving that the function has not been overriden.

This definitely looks like a bug to me. What do you think?

Regards,
Steve

LisburnLad
8 Jan 2012, 3:17 PM
I've now submitted a bug report for this problem:

http://www.sencha.com/forum/showthread.php?171546-4.1.0-B1-Ext.override-doesn-t-work-correctly-for-Ext.tree.Column

LisburnLad
9 Jan 2012, 2:36 PM
Evan Trimboli replied to the bug I'd submitted, pointing me in the direction of the breaking changes in 4.1.

It turns out that when overriding a class, that to now call the base class requires the use of "this.superclass.initComponent.call(this);", instead of "this.callParent(arguments);" which was previously used in 4.0.

Making this change fixes the problem.