Ext JS - Learning Center

Tutorial:Extending Ext for Newbies

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: A simple introduction to Extending ExtJs.
Author: Santosh Rajan
Published: September 18, 2008
Ext Version: 2.2
Languages: en.png Englishcn.png Chinese

Typically you want to embrace the power of Object Oriented design using classes. You do that for a few reasons as explained in this tutorial.

Reusable Classes

Sometimes you will have a component whose config options you want to make reusable. For example, you may have a set of panels with the same width and height, only the title is different. This is called a preconfigured class.

Constructor Model

One approach to accomplish this is to use a constructor function like this:

// MyPanel Extends Ext.Panel
MyPanel = Ext.extend(Ext.Panel, {
//  constructor function
    constructor: function(config) {
        Ext.apply(this, { 
            // Put your pre-configured config options here
            width: 300,
            height: 300
        });
        MyPanel.superclass.constructor.apply(this, arguments);
    }
});
 
var myfirstpanel = new MyPanel({
    title: 'My First Panel'
});
 
var mysecondpanel = new MyPanel({
    title: 'My Second Panel'
});

Factory Pattern

Another way to create preconfigured objects is by utilizing the factory design pattern. A factory function (a pre-configuring function) returns a new instance of the object. This approach does not require extending a class (so strictly speaking does not come under the scope of this discussion). The factory pattern is an alternative to the above method that is especially useful when the only thing you are doing is preconfiguring, not extending/overriding the base class behavior.

function createMyPanel(config) {
    return new Ext.Panel(Ext.apply({//Pre-configured config options go here
        width: 300,
        height: 300
    }, config));
};
 
var myfirstpanel = createMyPanel({
    title: 'My First Panel'
});
 
var mysecondpanel = createMyPanel({
    title: 'My Second Panel'
});

Extending Functionality

Another reason you want to use OO classes is that you want to extend the functionality of another class. Let us say you want to add a function in the above panel and override an existing function. This is one way to do it:

// Constructor
var MyPanel = function(config) {
    //Reusable config options here
    Ext.apply(this, {
        width: 300,
        height: 300
    });
    // And Call the superclass to preserve baseclass functionality
    MyPanel.superclass.constructor.apply(this, arguments);
    // Here you can add functionality that requires the object to exist, 
    // like event handling. 
    this.on('click', function() {alert("You Clicked " + this.title);}, this);
};
// MyPanel Extends Ext.Panel
Ext.extend(MyPanel, Ext.Panel, {
    // Here you can add static variables for the class. variables that will have 
    // the same value for all object instances of this class.
    // If you are not sure put it in the constructor above. Dont put any abject
    // created with 'new' or 'xtype' here. You are safer putting it in the config
    // option in the constructor.
 
    // New function added
    myNewFunction: function() {
    },
    // Override an existing function
    onRender: function() {
        MyPanel.superclass.onRender.apply(this, arguments);
        this.myNewFunction();
    }
});
 
var myfirstpanel = new MyPanel({
    title: 'My First Panel'
});
 
var mysecondpanel = new MyPanel({
    title: 'My Second Panel'
});

Another way to write the constructor above as shown by @Condor is:

var MyPanel = function(config) {
    // Call the superclass to preserve baseclass functionality
    MyPanel.superclass.constructor.call(this, Ext.apply({
        //Reusable config options here
        width: 300,
        height: 300
    }, config));
 
    // After superclass constructor add functionality that requires
    // the object to exist (like event handling...listeners)
    this.on('click', function() {alert("You Clicked " + this.title);}, this);
};

The above manner for extending an Ext class is the constructor model. Another way of extending an Ext class utilizes initComponent, one of the template methods Ext JS exposes just for this purpose. As you may have guessed this method is only applicable to extending Ext 'Components. Here is an example:

var MyPanel = Ext.extend(Ext.Panel, {
    // Here you can add static variables for the class. variables that
    // will have the same value for all object instances of this class.
    // If you are not sure put it in the constructor above. Do not  put
    // any object created with 'new' or 'xtype' here. It is safer to 
    // put it in the config option of the constructor.
 
    // New function added
    initComponent: function() {
        //Reusable config options here
        Ext.apply(this, {
            width: 300,
            height: 300
        });
       // And Call the superclass to preserve baseclass functionality
       MyPanel.superclass.initComponent.apply(this, arguments);
        // Here you can add functionality that requires the object to
        // exist, like event handling.
        this.on(
            'click',
            function() {
                alert("You Clicked " + this.title);
            },
            this
        );
    },
    myNewFunction: function() {
    },
    // Override an existing function
    onRender: function() {
        MyPanel.superclass.onRender.apply(this, arguments);
        this.myNewFunction();
    }
});

The first thing you will notice is that there is no constructor here. Ext creates the constructor for you. The constructor created by Ext will call initComponent. This is a widely used method you will find in the advanced tutorials and Examples. But just remember for now it does the same thing as the constructor model.

The preferred way to handle event handling (listeners) is to add them after the call to the superclass in the constructor or initComponent.

MyPanel.superclass.constructor.apply(this, arguments);
    // Here you can add functionality that requires the object to exist, 
    // like event handling. 
    this.on(
        'click',
        function() {
            alert("You Clicked " + this.title);
        },
        this
    );

In the case of the factory method you would add a event handler outside of the factory method like this.

myFirstPanel.on(
        'click',
        function() {
            alert("You Clicked " + this.title);
        },
        myFirstPanel //scope
    );

There are other ways of handling listeners notably by adding a listeners config option. But I would recommend that to advanced users.

There are many ways of doing the same thing in Ext JS. If you are spoiled for choice on which way to go, choose the one you are most comfortable with.

Further Reading:
1) Creating new UI controls
2) Saki's Tutorial: Extending Ext Class
3) mjlecomte's Sticky on Extending Ext Class
4) Discussion on this Tutorial

________________

  • This page was last modified on 23 March 2009, at 12:13.
  • This page has been accessed 20,501 times.