Skip to main content

Advanced concepts of Sencha Ext JS

- Ext.create

Instantiate a class by either full name, alias or alternate name.

If Ext.Loader is enabled and the class has not been defined yet, it will attempt to load the class via synchronous loading.

// alias
 var window = Ext.create('widget.window', {
     width: 600,
     height: 800,
     ...
 });

 // alternate name
 var window = Ext.create('Ext.Window', {
     width: 600,
     height: 800,
     ...
 });

 // full class name
 var window = Ext.create('Ext.window.Window', {
     width: 600,
     height: 800,
     ...
 });

 // single object with xclass property:
 var window = Ext.create({
     xclass: 'Ext.window.Window', // any valid value for 'name' (above)
     width: 600,
     height: 800,
     ...
 });
- Ext.define
define( className, data, createdFn ) : Ext.Base
Defines a class or override. A basic class is defined like this:

Ext.define('My.awesome.Class', {
     someProperty: 'something',

     someMethod: function(s) {
         alert(s + this.someProperty);
     }

     ...
 });

 var obj = new My.awesome.Class();

 obj.someMethod('Say '); // alerts 'Say something'
To create an anonymous class, pass null for the className:
Ext.define(null, {
     constructor: function () {
         // ...
     }
 });
In some cases, it is helpful to create a nested scope to contain some private properties. The best way to do this is to pass a function instead of an object as the second parameter. This function will be called to produce the class body:
Ext.define('MyApp.foo.Bar', function () {
     var id = 0;

     return {
         nextId: function () {
             return ++id;
         }
     };
 });
Example:
Ext.define ( String className, Object data, Function createdFn ) : Ext.Base
Ext.define is used to define a class. Example:

// creates My.computer.NoteBook Class
Ext.define('My.computer.NoteBook', {

     extend:'Ext.panel.Panel',

     config: {

          hardware:'Dell',
          os:'Linux',
          price:500
     },

     constructor:function(config) {

          this.initConfig(config);

          return this;
     }
});


// creates instance of My.computer.NoteBook Class
var myComputer = Ext.create('My.computer.NoteBook', {

     hardware:'MacBook Pro',
     os:'Mac OS X',
     price:1800
});
Ext.override
when using override, the above syntax will not override successfully, because the passed function would need to be executed first to determine whether or not the result is an override or defining a new object
Ext.define('MyApp.override.BaseOverride', function () {
     var counter = 0;

     return {
         override: 'Ext.Component',
         logId: function () {
             console.log(++counter, this.id);
         }
     };
 }());
To define an override, include the override property. The content of an override is aggregated with the specified class in order to extend or modify that class. This can be as simple as setting default property values or it can extend and/or replace methods. This can also extend the statics of the class.
One use for an override is to break a large class into manageable pieces.
// File: /src/app/Panel.js

 Ext.define('My.app.Panel', {
     extend: 'Ext.panel.Panel',
     requires: [
         'My.app.PanelPart2',
         'My.app.PanelPart3'
     ]

     constructor: function (config) {
         this.callParent(arguments); // calls Ext.panel.Panel's constructor
         //...
     },

     statics: {
         method: function () {
             return 'abc';
         }
     }
 });

 // File: /src/app/PanelPart2.js
 Ext.define('My.app.PanelPart2', {
     override: 'My.app.Panel',

     constructor: function (config) {
         this.callParent(arguments); // calls My.app.Panel's constructor
         //...
     }
 });
Another use of overrides is to provide optional parts of classes that can be independently required. In this case, the class may even be unaware of the override altogether.
 Ext.define('My.ux.CoolTip', {
     override: 'Ext.tip.ToolTip',

     constructor: function (config) {
         this.callParent(arguments); // calls Ext.tip.ToolTip's constructor
         //...
     }
 });
The above override can now be required as normal.
 Ext.define('My.app.App', {
     requires: [
         'My.ux.CoolTip'
     ]
 });
Overrides can also contain statics:
 Ext.define('My.app.BarMod', {
     override: 'Ext.foo.Bar',

     statics: {
         method: function (x) {
             return this.callParent([x * 2]); // call Ext.foo.Bar.method
         }
     }
 });
IMPORTANT: An override is only included in a build if the class it overrides is required. Otherwise, the override, like the target class, is not included.

To create a Panel with no header, configure it with header: false. This supercedes the preventHeader config option.
CallParent calls overridden method:
As part of formalizing Ext.define/override in Ext JS 4.1, it is now possible to name and require overrides just as you would a normal class:

Ext.define('My.patch.Grid', {
    override: 'Ext.grid.Panel',
    foo: function () {
        this.callParent(); // calls Ext.grid.Panel.foo
    }
});

The above code in Ext JS 4.0 would have called the base class foo method. You had to use the callOverridden to accomplish the above. In Ext JS 4.1, to bypass the overriden method, you just need to use the following code:
Ext.define('My.patch.Grid', {
    override: 'Ext.grid.Panel',
    foo: function () {
        Ext.grid.Panel.superclass.foo.call(this);
    }
});

Override Example:


Ext.define('Ext.some.Class', {
    method: function () {
        console.log('Good');
    }
});

Ext.define('Ext.some.DerivedClass', {
    method: function () {
        console.log('Bad');

        // ... logic but with a bug ...

        this.callParent();
    }
});

Ext.define('App.paches.DerivedClass', {
    override: 'Ext.some.DerivedClass',

    method: function () {
        console.log('Fixed');

        // ... logic but with bug fixed ...

        this.callSuper();
    }
});

Creating Custom Components

Composition or Extension
When creating a new UI class, the decision must be made whether that class should own an instance of a Component, or to extend that Component.
It is recommended to extend the nearest base class to the functionality required. This is because of the automated lifecycle management Ext JS provides which includes automated rendering when needed, automatic sizing and positioning of Components when managed by an appropriate layout manager, and automated destruction on removal from a Container.
It is easier to write a new class which is a Component and can take its place in the Component hierarchy rather than a new class which has an Ext JS Component, and then has to render and manage it from outside.
Ext.define('My.custom.Component', {
    extend: 'Ext.Component'
});
Template Methods

Ext JS uses the Template method pattern to delegate to subclasses, behavior which is specific only to that subclass.
Here is an example of a Component subclass that implements the onRender method:
Ext.define('My.custom.Component', {
    extend: 'Ext.Component',
    onRender: function() {
        this.callParent(arguments); // call the superclass onRender method

        // perform additional rendering tasks here.
    }
});

It is important to note that many of the template methods also have a corresponding event. For example the render event is fired after the Component is rendered. When subclassing, however, it is it is essential to use template methods to perform class logic at important phases in the lifecycle and not events. Events may be programmatically suspended, or may be stopped by a handler.

Below are the template methods that can be implemented by subclasses of Component:


initComponent This method is invoked by the constructor. It is used to initialize data, set up configurations, and attach event handlers.

beforeShow This method is invoked before the Component is shown.
onShow Allows addition of behavior to the show operation. After calling the superclass’s onShow, the Component will be visible.
afterShow This method is invoked after the Component is shown.
onShowComplete This method is invoked after the afterShow method is complete
onHide Allows addition of behavior to the hide operation. After calling the superclass’s onHide, the Component will be hidden.
afterHide This method is invoked after the Component has been hidden
onRender Allows addition of behavior to the rendering phase.
afterRender Allows addition of behavior after rendering is complete. At this stage the Component’s Element will have been styled according to the configuration, will have had any configured CSS class names added, and will be in the configured visibility and the configured enable state.
onEnable Allows addition of behavior to the enable operation. After calling the superclass’s onEnable, the Component will be enabled.
onDisable Allows addition of behavior to the disable operation. After calling the superclass’s onDisable, the Component will be disabled.
onAdded Allows addition of behavior when a Component is added to a Container. At this stage, the Component is in the parent Container's collection of child items. After calling the superclass's onAdded, the ownerCt reference will be present, and if configured with a ref, the refOwner will be set.
onRemoved Allows addition of behavior when a Component is removed from its parent Container. At this stage, the Component has been removed from its parent Container's collection of child items, but has not been destroyed (It will be destroyed if the parent Container's autoDestroy is true, or if the remove call was passed a truthy second parameter). After calling the superclass's onRemoved, the ownerCt and the refOwner will not be present.
onResize Allows addition of behavior to the resize operation.
onPosition Allows addition of behavior to the position operation.
onDestroy Allows addition of behavior to the destroy operation. After calling the superclass’s onDestroy, the Component will be destroyed.
beforeDestroy This method is invoked before the Component is destroyed.
afterSetPosition This method is invoked after the Components position has been set.
afterComponentLayout This method is invoked after the Component is laid out.
beforeComponentLayout This method is invoked before the Component is laid out.


Which Class To Extend

Choosing the best class to extend is mainly a matter of efficiency, and which capabilities the base class must provide. There has been a tendency to always extend Ext.Panel whenever any set of UI Components needs to be rendered and managed.
The Panel class has many capabilities:
  • Border
  • Header
  • Header tools
  • Footer
  • Footer buttons
  • Top toolbar
  • Bottom toolbar
  • Containing and managing child Components
If these are not needed, then using a Panel is a waste of resources.

Component

If the required UI Component does not need to contain any other Components, that is, if it just to encapsulate some form of HTML which performs the requirements, then extending Ext.Component is appropriate. For example, the following class is a Component that wraps an HTML image element, and allows setting and getting of the image's src attribute. It also fires a load event when the image is loaded:
Ext.define('Ext.ux.Image', {
    extend: 'Ext.Component', // subclass Ext.Component
    alias: 'widget.managedimage', // this component will have an xtype of 'managedimage'
    autoEl: {
        tag: 'img',
        src: Ext.BLANK_IMAGE_URL,
        cls: 'my-managed-image'
    },

    // Add custom processing to the onRender phase.
    // Add a ‘load’ listener to the element.
    onRender: function() {
        this.autoEl = Ext.apply({}, this.initialConfig, this.autoEl);
        this.callParent(arguments);
        this.el.on('load', this.onLoad, this);
    },

    onLoad: function() {
        this.fireEvent('load', this);
    },

    setSrc: function(src) {
        if (this.rendered) {
            this.el.dom.src = src;
        } else {
            this.src = src;
        }
    },

    getSrc: function(src) {
        return this.el.dom.src || this.src;
    }
});
Usage:
var image = Ext.create('Ext.ux.Image');

Ext.create('Ext.panel.Panel', {
    title: 'Image Panel',
    height: 200,
    renderTo: Ext.getBody(),
    items: [ image ]
});

image.on('load', function() {
    console.log('image loaded: ', image.getSrc());
});

image.setSrc('http://www.sencha.com/img/sencha-large.png');
Containers have the following additional template methods:
  • onBeforeAdd This method is invoked before adding a new child Component. It is passed the new Component, and may be used to modify the Component, or prepare the Container in some way. Returning false aborts the add operation.
  • onAdd This method is invoked after a new Component has been added. It is passed the Component which has been added. This method may be used to update any internal structure which may depend upon the state of the child items.
  • onRemove This method is invoked after a new Component has been removed. It is passed the Component which has been removed. This method may be used to update any internal structure which may depend upon the state of the child items.
  • beforeLayout This method is invoked before the Container has laid out (and rendered if necessary) its child Components.
  • afterLayout This method is invoked after the Container has laid out (and rendered if necessary) its child Components.

Panel

If the required UI Component must have a header, footer, or toolbars, then Ext.Panel is the appropriate class to extend.
Important: A Panel is a Container. It is important to remember which Layout is to be used to render and manage child Components.
Classes which extend Ext.Panel are usually highly application-specific and are generally used to aggregate other UI Components (Usually Containers, or form Fields) in a configured layout, and provide means to operate on the contained Components by means of controls in the tbar and the bbar.
Panels have the following additional template methods:
  • afterCollapse This method is invoked after the Panel is Collapsed.
  • afterExpand This method is invoked after the Panel is expanded
  • onDockedAdd This method is invoked after a docked item is added to the Panel
  • onDockedRemove This method is invoked after a docked item is removed from the Panel

Comments

Post a Comment

Popular posts from this blog

ExtJS - Grid panel features

What can we do with ExtJS GridPanel? I have to develop a lot of applications in my web app and I see that grid component of ExtJS may fit in. However, I am not aware of what all things I can do with the - off the shelf available framework pieces - available plug-ins in the marketplace and - custom development through my own developers This is a typical question that we hear from the business users who wants to design an application by keeping the framework’s capability in perspective. In this article I have tried to put the list of stuff you can do with grid and hopefully that shall enable you to take advantage of the beauty of ExtJS. Pre-requisites This article assumes that you are familiar with basics of ExtJS What are the available options? In this section I will be taking you through some of the commonly seen usage of ExtJS grid panel. While covering all the capabilities of grid may not be possible, I am sure it will be helpful for the business users who want to...

ExtJS 4 with Spring MVC Example

Introduction When developing a brand new application for the company I work for, one of the first thing I implement is "authentication". Not only is this process generally a prerequisite to access many other functions but it is also very simple and covers every layer of an application, from GUI to the database. So instead of another minimalistic "Hello World" tutorial, here is a "Login/Password" example, using 2 famous technologies : Spring MVC and ExtJS 4.   Prerequisites Because this tutorial is quite long, I won't go into the details of each technology I used but I will mainly focus on how ExtJS and Spring can be nicely used together. So here are the things you should know before continuing : Spring framework (good knowledge) Spring MVC (basic knowledge. See  Spring MVC Official Documentation  for details) ExtJS "application architecture" (see  Sencha Docs  for details) Eclipse IDE + Tomcat 6 (or any other web container) You a...

Ext4 Apply Store Filtering

In extjs4.1: There are many way for store filtering . Some of code i give here Filtering by single field: store . filter ( 'eyeColor' , 'Brown' );   Alternatively, if filters are configured with an  id , then existing filters store may be  replaced by new filters having the same  id . Filtering by single field: store . filter ( "email" , /\.com$/ );   Using multiple filters: store . filter ([ { property : "email" , value : /\.com$/ }, { filterFn : function ( item ) { return item . get ( "age" ) > 10 ; }} ]);   Using  Ext.util.Filter  instances instead of config objects (note that we need to specify the root config option in this case): store . filter ([ Ext . create ( ' Ext.util.Filter ' , {   property : "email" , value : /\.com$/ , root : 'data' }),   Ext . create ( ' Ext.util.Filter ' , {   filterFn : function ( item ) {   return item . get ( ...