Developing with Extjs - tricks and tips.
Published 2007-05-16 16:38:00
I thought I'd go some of my random thoughts of working with extjs, as creating quite large applicaitons with extjs is quite new, and as the projects I've used it on have been refactored a few times, I'm beginning to develop approaches that make code more maintainable, and faster to develop.
This is quite a big post - so the contents in the Extended body....
This is quite a big post - so the contents in the Extended body....
Defining objects
Since Javascript doesnt have namespaces, or the class keyword, there are a number of ways objects can be defined. Often an object in js is just a way to reduce the polution of the namespace with global functions.The simplest way to define a class is for static use
aaa = {
ccc: "test",
bbb : function() { alert(this.cc); }
}
aaa.bbb();
I'm comming to the conclusion that this is the best way to deal with code that will only have one instance, eg the main layout, or a widget.
You cannot instantate this as an object (no "new" needed), extending it is possible, (although I've not tested this idea yet), Most of the User Interface creation and reaction code is now being written this way.
It has a number of advantages over the next method, for developing, as accessing the variables for debugging is feasible.
This is really a evolution for my old code as well, as previously I tended to use function name prefixes, and binding that into the object.
Class definitions with private variables
aaa = (function () {
var myprivate;
return {
setIt: function(val) { myprivate = val; }
getIt: function() { return myprivate; }
}
})();
This method is common in extjs for libraries where Jack does not want users changing or reading the private variables. It however leaves you with the problem that inspecting those variable for debuging is difficult. It has a slight benefit that you can avoid putting "this." to access your private variables.
Extending objects with Ext.extend
function MyCombo (config) {
// set up your datasource here..
MyCombo.superclass.constructor.call(this,config);
}
Ext.extend(MyCombo, Ext.form.ComboBox, {
displayField:'title',
typeAhead: true,
loadingText: 'Searching...',
forceSelection: true,
allowBlank: false,
width: 160,
minChars: 1,
pageSize:10,
hideTrigger:true,
displayField: 'FullName',
valueField: 'id'
}
This resembles the more classic object definition pattern, and is the core behind extjs. It's handy for writing common reusable components, and extending extjs objects to create your application specific widgets.
Fixing bugs and miss-behaviour in extjs
Every so often when using extjs, you come across issues with the libraries that result in widgets not behaving how you want them to (or expect them to.).To fix this you have a few options
- redeclare the whole class.
- extend the class overriding the methods or properties that you need fixed.
-
overide one or more of the objects prototypes
eg. Fix to use the input maxWidth field - so that overtyping results in chopped data.
Ext.form.TextField.prototype.initValue = function()
{
if(this.value !== undefined){
this.setValue(this.value);
}else if(this.el.dom.value.length > 0){
this.setValue(this.el.dom.value);
}
if (!isNaN(this.maxLength) &&
(this.maxLength *1) > 0 &&
(this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
};
write - test - fix cycle
I normally use write on commit with an svn mounted drive, so after saving the file in my editor, I can reload the page from a remote server in firefox. The only snag with this approach is that I'm often only editing a small part of the application, and reloading the whole lot is both timeconsuming (well a second or two!) and a little network intensive..As I have been breaking the classes that deal with specific area's of the code into seperate .js files, I really only need to reload that js file. So after a bit of googling and hacking I came up with this simple funciton. -
include = function(url){
var con = new Ext.data.Connection();
con.request({
url: url + '?ts=' + (new Date().format('Ymd_his')),
method: 'GET',
callback: function(opts, success, response) {
if (!success) {
Ext.MessageBox.alert("Error",
success ? response.responseText :
"Error saving data - try again");
return;
}
var o = document.getElementById('script_' + url)
if (o) {
o.parentNode.removeChild(o);
}
s = document.createElement('script');
s.setAttribute('id', 'script_' + url);
s.setAttribute('type', 'text/javascript');
s.appendChild(document.createTextNode(response.responseText));
document.getElementsByTagName("head")[0].appendChild(s);
}
});
}
I tried various other methods, like adding <script> tags with src in DOM, but the browser refused to refresh the code.. - so this method of dumping the source inside of a script tag seems to work best for testing.
It works pretty much like good ole PHP's include method. eg.
include("MyProject/templates/images/js/mylib.js");
Which can be run at the command line in firebug. Refreshing the object definition, enabling me to test changes to dialogs and forms without having to reload the whole page.
I guess hoping that Ctrl-S in the editor could trigger that to happen automatically may be going a bit far...
HTML morphing or just javascript
When I started using extjs, I had tried out dojo, and quite liked the way it used HTML attributes to create dynamic components. I had got to the point of writing simple Helper Class to convert tables and forms into grids and forms with Ext.form elements, and although it worked. I later attempted to just define my dialog, form and grids directly only using javascript and extjs.
Having tried this alternative, it's pretty clear that the original idea of using HTML attributes doesnt really have much advantage, and espicially combined with the include() method the idea of using pure javascript to define these components has proved far more efficient. In reality I dont think I will resort to HTML for much more than text content areas that need rendering. The whole layout, dialogs, forms etc will now be purely done in Javascript.
Moving to Extjs's XMLHttpRequest call.
As usual when you start using a library, You never get time to learn the whole thing, so I had initially been relying on my old XMLHttpRequest wrapper to send data to the server, but as I began to dig deeper into extjs, I was able to start removing my old Wrapper code and use the code in extjs. Which Is better tested (as my library was originally morphed from some code that worked with the XUL app's I was writing). And also alot more powerfull.
The save code for my dialogs looks a bit like this..
dialog.el.mask("Saving...");
var con = new Ext.data.Connection();
con.request({
url: baseURL + "/mypage.txt", // where to post to..
params: params, // << key value object with data to send
method: 'POST',
callback: function(opts, success, response) {
dialog.el.unmask(true); // unmask the dialog.
if (!success || ("OK" != response.responseText)) {
Ext.MessageBox.alert("Error", success ?
response.responseText :
"Error saving data - try again");
return;
}
dialog.hide();
// code to update stuff that's affected by the saved form working..
// goes here...
}
});
Submitting forms.
Having moved to using Ext.form.Form, one snag I did find was that the default method for getting form values wasvar ar = form.getValues();
unfortunatly, this urlencodes both the key and value of the data, so using that with the code above to send the data makes a complete mess..
This little trick helps solve that..
Ext.form.Form.prototype.getValuesRaw = function() {
var ar = this.getValues();
var ret = {};
for(var i in ar) {
ret[decodeURIComponent(i)] = decodeURIComponent(ar[i]);
}
return ret;
};
Comboboxes - load once, not all the time.
The combo box on ExtJs, can autocompelete using JSON calls to the server, With lists that dont change often, I considered this a bit of an overkill, so by calling the load method in the extended class, and setting the mode to 'local', I was able to deliver a more efficient combo.function myCombo() {
this.Store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: baseURL + '/MyLister.js'
}),
reader: new Ext.data.JsonReader({
root: 'data',
totalProperty: 'totalCount',
id: 'id'
}, [ 'id', 'fullname' ])
});
}
this.Store.load();
config.store = this.Store;
myCombo.superclass.constructor.call(this, config);
}
Ext.extend(FlexyCash.AccountCombo, Ext.form.ComboBox, {
mode: 'local',
.....
});
Then if you need to refresh the list at any time (eg. before the dialog appears), just call the combo.store.load() method..
IE Gotcha's
Normally when I do any web development, It seems like 20% at the end of the project is spent working around IE bugs, so even with my extjs projects I've been developing in firefox and testing later with IE. However the only serious issue that I've found that catches me out has been that IE doesnt like trailing comma's in object definitions.
var a = {Otherwise It's pretty easy going developing cross platform applications with extjs..
a: "b",
c: "d", //<< oops trailing comma!
};
Mentioned By:
www.dzone.com : Developing with Extjs - tricks and tips. (6206 referals)
google.com : extjs (519 referals)
google.com : Ext.data.Connection (313 referals)
google.com : extjs XMLHttpRequest (206 referals)
www.phpeye.com : Developing with Extjs - tricks and tips. - Alan Knowles|PHP教程|PHP实例|PHP新闻|PHP5|PEAR|PHP框架|PHPEye - Powered by Ha (176 referals)
www.stumbleupon.com : StumbleUpon » Your page is now on StumbleUpon! (169 referals)
google.com : extjs combobox (164 referals)
www.blinklist.com : Discover the best extjs and extjs sites (158 referals)
swik.net : AKBK home - Smoking toooooo much PHP - Developing with Extjs - tricks and tips. - SWiK (138 referals)
www.gennio.com : extjs en Gennio (131 referals)
google.com : extjs json (121 referals)
www.megite.com : Discover From Your Favorite Topic or Web Page: extjs (119 referals)
google.com : extjs forms (109 referals)
google.com : april (103 referals)
www.phpchina.com : Developing with Extjs - tricks and tips. - Dennis's Blog - PHPChina ԴŻ - Powered by X-Space (94 referals)
google.com : Ext.form.combobox (74 referals)
www.megite.com : Discover From Your Favorite Topic or Web Page: extjs json (73 referals)
www.planet-php.net : Planet PHP (72 referals)
google.com : extjs alternative (69 referals)
google.com : december (68 referals)
www.dzone.com : Developing with Extjs - tricks and tips. (6206 referals)
google.com : extjs (519 referals)
google.com : Ext.data.Connection (313 referals)
google.com : extjs XMLHttpRequest (206 referals)
www.phpeye.com : Developing with Extjs - tricks and tips. - Alan Knowles|PHP教程|PHP实例|PHP新闻|PHP5|PEAR|PHP框架|PHPEye - Powered by Ha (176 referals)
www.stumbleupon.com : StumbleUpon » Your page is now on StumbleUpon! (169 referals)
google.com : extjs combobox (164 referals)
www.blinklist.com : Discover the best extjs and extjs sites (158 referals)
swik.net : AKBK home - Smoking toooooo much PHP - Developing with Extjs - tricks and tips. - SWiK (138 referals)
www.gennio.com : extjs en Gennio (131 referals)
google.com : extjs json (121 referals)
www.megite.com : Discover From Your Favorite Topic or Web Page: extjs (119 referals)
google.com : extjs forms (109 referals)
google.com : april (103 referals)
www.phpchina.com : Developing with Extjs - tricks and tips. - Dennis's Blog - PHPChina ԴŻ - Powered by X-Space (94 referals)
google.com : Ext.form.combobox (74 referals)
www.megite.com : Discover From Your Favorite Topic or Web Page: extjs json (73 referals)
www.planet-php.net : Planet PHP (72 referals)
google.com : extjs alternative (69 referals)
google.com : december (68 referals)
Follow us
-
- Some thoughts on the language server and its usefulness in the roobuilder
- Roo Builder for Gtk4 moving forward
- Clustered Web Applications - Mysql and File replication
- GitLive - Branching - Merging
- PDO_DataObject Released
- PDO_DataObject is under way
- Mass email Marketing and anti-spam - some of the how-to..
- Hydra - Recruitment done right
Blog Latest
-
Twitter - @Roojs