This is take 2 of the observable / plugin combination. The first post is here: http://www.sencha.com/forum/showthre...ponent-plugins
The idea is to have plain javascript objects easily support plugins. Just paste this html into a file in the root of your ext4 installation and you are good to go!
Code:
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Ext.AbstractObject</title>
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="examples/shared/example.css" />
<script type="text/javascript" src="bootstrap.js"></script>
<script type="text/javascript">
var out;
Ext.onReady(function () {
out = Ext.get("output");
});
function output ( msg ) {
out.insertHtml("beforeEnd", msg + "<br>");
// console.log(msg);
}
/**
* @class Ext.AbstractObject
* Shared base object class
* <p>Base class for any object requiring events and plugin support.</p>
* @constructor
* @param {Ext.Element/String/Object} config The configuration options
*/
Ext.define("Ext.AbstractObject", {
/**
* @cfg {Object/Array} plugins
* An object or array of objects that will provide custom functionality for this component. The only
* requirement for a valid plugin is that it contain an init method that accepts a reference of type Object.
* When a component is created, if any plugins are available, the component will call the init method on each
* plugin, passing a reference to itself. Each plugin can then call methods or respond to events on the
* component as needed to provide its functionality.
*/
extend : "Ext.util.Observable",
constructor : function( config ) {
config = config || {};
this.callParent([config]);
this.constructPlugins();
this.initObject();
this.initPlugins();
},
initObject : Ext.emptyFn,
constructPlugins : function() {
var me = this;
if ( me.plugins ) {
me.plugins = [].concat(me.plugins);
for (i = 0, len = me.plugins.length; i < len; i++) {
me.plugins[i] = me.constructPlugin(me.plugins[i]);
}
}
},
constructPlugin : function( plugin ) {
if ( plugin.ptype && (typeof plugin.init != "function") ) {
plugin.obj = this;
plugin = Ext.PluginMgr.create(plugin);
}
else if ( typeof plugin == "string" ) {
plugin = Ext.PluginMgr.create({
ptype : plugin,
obj : this
});
}
return plugin;
},
initPlugins : function() {
var me = this;
if (me.plugins) {
me.plugins = [].concat(me.plugins);
for (i = 0, len = me.plugins.length; i < len; i++) {
me.plugins[i] = me.initPlugin(me.plugins[i]);
}
}
},
initPlugin : function( plugin ) {
plugin.init(this);
return plugin;
}
});
/* ------------------------------------------------------------ */
// Examples
/* ------------------------------------------------------------ */
// simple plugin
Ext.define("MyPlugin", {
alias : "plugin.my-plugin",
init : function( obj ) {
output(obj.$className + " MyPlugin constructor");
}
});
// Three different ways to construct/init a plugin
// 1) ptype as a property in an object
// 2) init function as a property in an object
// 3) ptype as a string
// Use AbstractObject as a mixin
Ext.define("CanSing", {
plugins : [{ptype : "my-plugin"}], // (1) ptype as a property in an object
mixins : {
object : "Ext.AbstractObject"
},
constructor : function ( config ) {
output("CanSing constructor before AbstractObject");
this.mixins.object.constructor.call(this, config);
output("CanSing constructor after AbstractObject");
},
initObject : function () {
output("CanSing initObject called from AbstractObject");
}
});
// Use AbstractObject as a parent
Ext.define("Musician", {
extend : "Ext.AbstractObject",
plugins : [
{init : function () { output("Musician plugin.init") }}, // (2) init function as a property in an object
"my-plugin" // (3) ptype as a string
],
constructor : function ( config ) {
output("Musician constructor before AbstractObject");
this.callParent([config]); // construct AbstractObject
output("Musician constructor after AbstractObject");
},
initObject : function () {
output("Musician initObject called from AbstractObject");
}
});
// Global so you can inspect in firebug
var sing, music;
Ext.onReady(function () {
output("<b>About to construct CanSing</b>");
sing = new CanSing({singing : true});
output("<b>About to construct Musician</b>");
music = new Musician({playing : true});
});
</script>
</head>
<body>
<h1>Ext.AbstractObject</h1>
<p>The example shows how to use the AbstractObject class. Use firebug to see the code.</p>
<p id="output"></p>
</body>
</html>