PDA

View Full Version : Ext.Loader - Loading custom built components



EloB
27 Feb 2009, 3:09 AM
Hi!

Ive just completed my custom built component loader! This is a perfect function for huge dynamic webb applications that contains hundreds of javascript classes and you would like to have seperate files for each class for the readability.

Ext.Loader(config)

Configuration
(Array) require: OPTIONAL with required classes as string and preloads if doesnt loaded.
Example: ['Example.Grid.Store'] will append <script type="text/javascript" src="Example/Grid/Store.js"></script> and wait until that Class has loaded with its requires recursivly.

(String) namespace: OPTIONAL where to put the created class, default window

(String) cls: the classname

(String) extend: OPTIONAL the extended classname

(Function) construct: OPTIONAL the constructor, to call parent construct then use
arguments.callee.superclass.constructor.apply(this, arguments)

(Function) define: OPTIONAL MUST return the prototype object. Why isnt this a object? Because of private methods/properties possiblity when its a function.

(Function) main: OPTIONAL This is runned after the class has loaded!

But here is an example:



<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title>Example</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link href="css/ext-all.css" media="screen" rel="stylesheet" type="text/css" />
</head>

<body>
<script type="text/javascript" src="ext-base.js"></script>
<script type="text/javascript" src="ext-all-debug.js"></script>
<script type="text/javascript" src="ext-loader.js"></script>
<script type="text/javascript" src="Example/Start.js"></script>
</body>

</html>
You can follow the loading action in your firebug!

/Example/Start.js


Ext.Loader(
{
require: [
'Example.Grid',
'Example.Panel'
],

namespace: 'Example',

cls: 'Start', extend: 'Ext.Viewport',

construct: function(config, message) {
this.setMessage('Monkey island');
arguments.callee.superclass.constructor.apply(this, arguments)
},

define: function() {
var _message;

return {
layout: 'border',
getMessage: function() {
return _message;
},
setMessage: function(message) {
_message = message;

return this;
},
toString: function() {
return this.getMessage();
}
};
},

main: function() {
console.log('Loaded class: %s', 'Example.Start');
new Example.Start({ items: new Example.Panel() }, 'Monkey island');
}
}
);


/Example/Grid.js


Ext.Loader(
{
require: ['Example.Grid.Store'],

namespace: 'Example',

cls: 'Grid', extend: 'Ext.grid.GridPanel',

main: function() {
console.log('Loaded class: %s', 'Example.Grid');
}
}
);

/Example/Grid/Store.js


Ext.Loader(
{
namespace: 'Example.Grid',

cls: 'Store', extend: 'Ext.data.JsonStore',

main: function() {
console.log('Loaded class: %s', 'Example.Grid.Store');
}
}
);


/Example/Panel.js


Ext.Loader(
{
namespace: 'Example',

cls: 'Panel', extend: 'Ext.Panel',

define: function() {
return {
title: 'MyPanel',
region: 'center'
};
},

main: function() {
console.log('Loaded class %s', 'Example.Panel');
}
}
);


ext-loader.js


/**
* @author Olle Bröms
*/
(
function() {
var
Event = Ext.EventManager,
Dom = Ext.DomHelper;

var
_loads = {},
_ready = {},
_class = {},
_await = {};

var Loader = Ext.extend(
Ext.util.Observable,
{
constructor: function() {
this.addEvents({ load: true });
}
}
);

function onLoad(classname) {
var
await = _await[this.fullname],
complete = true;

delete await[classname];

for(var ix in await) {
complete = false;
break;
}

if(complete) {
onReady.call(this);
}
}

function onReady() {
var
namespaces = this.fullname.split('.'),
cls = window;

for(var i = 0; i < namespaces.length; i++) {
if(cls[namespaces[i]]) {
cls = cls[namespaces[i]];
} else {
cls = cls[namespaces[i]] = function() {
this.constructor.apply(this, arguments);
};
}
}

if(this.extend) {
var extend = window;

namespaces = this.extend.split('.');

for(var i = 0; i < namespaces.length; i++) {
extend = extend[namespaces[i]];
}

var define = this.define();

if(this.construct) {
define.constructor = this.construct;
}

var extended = Ext.extend(extend, define);

cls.constructor = extended;
cls.prototype = extended.prototype;
} else {
cls.constructor = this.construct;
cls.prototype = this.define();
}

if(this.main) {
this.main();
}

_ready[this.fullname] = true;

if(_loads[this.fullname]) {
_loads[this.fullname].fireEvent('load', this.fullname);
}
}

Ext.Loader = function(config) {
var fullname = [];

if(config.namespace) {
fullname[fullname.length] = config.namespace;
}

if(config.cls) {
fullname[fullname.length] = config.cls;
}

fullname = fullname.join('.');

_class[fullname] = config;

_class[fullname].fullname = fullname;
_class[fullname].define = _class[fullname].define || function() { return {}; };

_await[fullname] = {};

var await = false;

if(config['require']) {
var requires = config['require'];
for(var i = 0; i < requires.length; i++) {
var require = requires[i];
if(!_ready[require]) {
await = true;

_await[fullname][require] = true;

if(!_loads[require]) {
_loads[require] = new Loader();
_loads[require].on('load', onLoad, _class[fullname]);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = require.replace(/\./g, '/') + '.js';
Ext.getBody().appendChild(script);
} else {
_loads[require].on('load', onLoad, _class[fullname]);
}
}
}
}

if(!await) {
onReady.call(_class[fullname]);
}
};
}
)();

emkramer
12 May 2011, 6:02 AM
:((

I tried following your example and I get an error,

"Ext.Loader is not a function"

anyone know why?