开发者

Extjs How to initialize new elements when extending - without losing scope

开发者 https://www.devze.com 2023-01-05 10:27 出处:网络
I am trying to get better at extending the classes of Extjs, and my evolvement have lead me to this problem:

I am trying to get better at extending the classes of Extjs, and my evolvement have lead me to this problem:

I have extended an Ext.Panel and I want my extension to have a bottom toolbar with one button as default.

myPanel = Ext.extend(Ext.Panel, {
    method: function () {
        return 'response!';
    },

    bbar: new Ext.Toolbar({
        items:
        [
            {
                xtype: 'button',
                text: 'Hit me!',
                handler: function (button, event) {
                    alert(this.method());
    开发者_StackOverflow中文版            },
                scope: this
            }
        ]
    })
});

What I haven't learnt yet is why this is not allowed. this is pointing at the global scope and not my extended panel - thus .method() is undefined inside the handler function.


You're defining the bbar on the prototype rather than on a specific object.

Override initComponent and move the bbar definition inside it.

myPanel = Ext.extend(Ext.Panel, {
    method: function () {
        return 'response!';
    },

    initComponent: function() {    
        var bbar = new Ext.Toolbar({
            items:
            [
                {
                    xtype: 'button',
                    text: 'Hit me!',
                    handler: function (button, event) {
                        alert(this.method());
                    },
                    scope: this
                }
            ]
        });

        // Config object has already been applied to 'this' so properties can 
        // be overriden here or new properties (e.g. items, tools, buttons) 
        // can be added, eg:
        Ext.apply(this, {
            bbar: bbar
        });

        // Call parent (required)
        myPanel.superclass.initComponent.apply(this, arguments);

        // After parent code
        // e.g. install event handlers on rendered component
    }
});

See http://www.sencha.com/learn/Manual:Component:Extending_Ext_Components for a template you can use when extending components


You have to keep in mind that the anonymous object that is the first element of the items array is created in the same scope as the one in which Ext.extend(... is executed.

If you had this:

var o = { 'a': a, 'b': b, scope: this };

you would expect that o.a, o.b, and o.scope would have the same values as a, b, and this in the current scope. Here, it's a little more complex because you are creating an object while creating an array while creating an object, etc., but the reasoning is the same.

What you should do instead is define this.bbar inside the constructor:

myPanel = Ext.extend(Ext.Panel, {
    method: function () {
        return 'response!';
    },

    constructor: function(config) {
        this.bbar = new Ext.Toolbar({
            items:
            [
                {
                    xtype: 'button',
                    text: 'Hit me!',
                    handler: function (button, event) {
                        alert(this.method());
                    },
                    scope: this
                }
            ]
        });

        myPanel.superclass.constructor.apply(this, arguments);
    }
});
0

精彩评论

暂无评论...
验证码 换一张
取 消