four ways to add features to ext js
TRANSCRIPT
Adding Features to Ext JS
Get Ext JS to do your bidding
Options
● Extend● Override● Plugin● Sequence/Intercept
Extending
New component based on another
Inherits functionality
Somewhat lightweight (well come back to this)
Four step process
Basic Extending
Pick a class to start from (well come back to this)
CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {}}); Ext.reg('custompanel', CustomPanel);
Basic Extending
Configure it with initComponent (well come back to this) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {}}); Ext.reg('custompanel', CustomPanel);
Basic Extending
Add your own methods (or override existing) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {}}); Ext.reg('custompanel', CustomPanel);
Basic Extending
Register it (for use as an xtype) CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() { CustomPanel.superclass.overriddenMethod.call(this); }}); Ext.reg('custompanel', CustomPanel);
Basic Extending
Party (like it's 1999)
var myPanel = new CustomPanel({border: true});
...items: [{ xtype: 'custompanel', border: true }]
Extend From...
Classes that only need events should extend Ext.util.Observable
Classes that will serve as UI widgets should extend Ext.Component
Use Ext.BoxComponent if simple layout management will be necessary
Classes that can contain other components should extend Ext.Container Classes that require a title bar, toolbar or other advanced display features should extend Ext.Panel Look at the docs to see the inheritance chain for classes (upper right corner)
How much overhead does extending add?
Overhead
Only as much code as you add CustomPanel = Ext.extend(Ext.Panel, { initComponent : function() { Ext.apply(this, { title: 'My Custom Panel' }); CustomPanel.superclass.initComponent.call(this); }, newMethod: function() {}, overriddenMethod: function() {}}); Ext.reg('custompanel', CustomPanel);
Prototypical Inheritance
Ugly word, great for memory usage
Extending does not copy, it creates memory pointers.
.constructor
Override
Overwrites existing library code
Used to change base functionality or fix bugs
Can be evil (don't let it become your crutch)
Keep separate from the your code (ie: overrides.js)
Basic Override
// Class definition ExtClass = Ext.extend(Ext.Component, { existingMethod: function() {} overriddenMethod : function() {}}); // Our override Ext.override(ExtClass, { newMethod : function() {}, overriddenMethod : function() {}});
Basic Override
existingMethod remains newMethod is added (does not exist yet)overriddenMethod is completely replaced (exists already)
// Class definition ExtClass = Ext.extend(Ext.Component, { existingMethod: function() {} overriddenMethod : function() {}}); Ext.override(MyClass, { newMethod : function() {}, overriddenMethod : function() {}});
Plugins
Adds functionality to various classes
Can be used on any class that inherits from Ext.Component
Independent of base class (more on this later)
Basic Plugin
Extend a base class (usually a simple one)
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff }});Ext.preg('plugin-name',Ext.ux.PluginName);
Basic Plugin
Process any plugin configuration (can be omitted)
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff }});Ext.preg('plugin-name',Ext.ux.PluginName);
Basic Plugin
Do stuff on host class initialization
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff }});Ext.preg('plugin-name',Ext.ux.PluginName);
Basic Plugin
Register the plugin
Ext.ux.PluginName = Ext.extend(Ext.util.Observable, { constructor: function(config){ Ext.apply(this,config); Ext.ux.PluginName.superclass.constructor.call(this, config); }, init: function(cmp){ // do stuff }});Ext.preg('plugin-name',Ext.ux.PluginName);
We Have a Plugin
Party (like it's 1999) again
...items: [{ xtype: 'custompanel', border: true, plugins: [{ ptype: 'plugin-name', isAwesome: false }]}]
Not awesome yet?
(lets make it awesome)
Awesome Plugin
The magic happens here
init: function(cmp){ this.hostCmp = cmp cmp.setTitle('Awesome'); }
init is called just after initComponent but before render
Sequence/Intercept
Piggyback on existing functions
Useful for small changes/features
Be aware of impact
Basic Sequence/Intercept
Intercept happens before
Sequence happens after
Basic Sequence/Intercept
Class and method to sequence or intercept
Ext.intercept(Ext.form.Field.prototype, 'initComponent', function() {var fl = this.fieldLabel, ab = this.allowBlank;if (ab === false && fl) {this.fieldLabel = '<span style="color:red;">*</span> '+fl;} else if (ab === true && fl) {this.fieldLabel = ' '+fl;}});
Basic Sequence/Intercept
Scope and arguments remain the same
Ext.intercept(Ext.form.Field.prototype, 'initComponent', function() {var fl = this.fieldLabel, ab = this.allowBlank;if (ab === false && fl) {this.fieldLabel = '<span style="color:red;">*</span> '+fl;} else if (ab === true && fl) {this.fieldLabel = ' '+fl;}});
Basic Sequence/Intercept
...{ fieldLabel: 'Last Name', allowBlank: false, name: 'last'},{ß fieldLabel: 'Company', allowBlank: true, name: 'company'}...