Reputation: 3091
I have a view that configures its items dynamically. Those child items also configure themselves dynamically.
I'm trying to use initComponent, but in the code below, the merest presence of initComponent on the childItem results in an error ("Cannot read property 'length' of undefined").
Without initComponent on the childItem, the rest works.
What's going wrong with this? Is there an alternative approach?
Ext.define('myapp.view.MyView', {
extend: 'Ext.container.Container',
initComponent: function () {
var me = this;
var childItem = {
xtype: 'container',
initComponent: function () {
var me = this;
// I want the childItem to do some configuration here.
me.callParent();
}
};
me.items = [
childItem
];
me.callParent();
}
});
Upvotes: 1
Views: 6749
Reputation: 995
You can use the undocumented xhooks
config for Components. See this.
Ext.ComponentManager.create({
xtype: 'panel',
xhooks: {
initComponent: function() {
console.log('in local override for this specific instance of panel');
this.items = [{
xtype: 'panel',
xhooks: {
initComponent: function() {
console.log('in local override for this specific instance of panel');
this.items = [{html: 'hi'}];
this.callParent();
}
}
}];
this.callParent();
}
}
}, 'panel');
During the component creation process, when Ext sees an xhooks
property it overrides the current instance's functions with the matching functions contained in the xhooks
config. This ensures that callParent
works.
Upvotes: 3
Reputation: 4405
You are not extending an Ext.Container correctly in your code. If you want to override initComponent
, use Ext.define
to define your class first:
Ext.define('MyContainer', {
extend: 'Ext.Container',
alias: 'widget.my-ct',
initComponent: function () {
var me2 = this;
// I want the childItem to do some configuration here.
me2.callParent();
}
});
Ext.define('myapp.view.MyView', {
extend: 'Ext.container.Container',
initComponent: function () {
var me = this;
var childItem = {
xtype: 'my-ct'
};
me.items = [
childItem
];
me.callParent();
}
});
As a best practice, you should always define your classes in separate files. I thought that this would be common sense and just wanted to explain why your original code was in error, but the comment section complained so I've changed this to use more appropriate code.
Upvotes: 2
Reputation: 25041
callParent
will work only with methods that have been passed through Ext.define
(or a close equivalent). Here, you're doing a "runtime" override, so callParent
won't work for the children.
Your most next-developer-friendly option is to turn those into legitimate Ext overrides. You can use anonymous classes for simplicity's sake. Example:
var childClass = Ext.define(null, {
extend: 'Ext.container.Container'
,initComponent: function() {
// Here that will work
this.callParent(arguments);
}
});
var childItem = new childClass;
// ...
The other option is to do the work of callParent
yourself by calling the parent method in the right scope. The catch here is that you must know how to access the parent method, however this option is nice for bragging about your javascript skills since it will result in some barbarian syntax most (non javascript) developers won't be able to figure out ;) In your case, replace this.callParent()
in your child with:
Ext.container.Container.prototype.initComponent.apply(this, arguments);
In both cases, don't forget that you must require Ext.container.Container
. In the first case, that will ensure the code runs synchronously, and in the second case it will avoid it to crash on undefined class.
Upvotes: 0