Posted by:
Jozef Sakalos, aka SakiArticle original:
Creating a complex application in Ext on blog.extjs.eu
Foreword
I decided to write this article for those
Ext 2.x users who have already outgrown a single HTML page with embedded script that creates a simple window or form, for those who have already decided that Ext is their way and for those who are overcoming difficulties associated with large amounts of code, understand that they need to be structured.
How many people, so many opinions. And so the method that I will describe below is not the only one possible. I would also like to note that not every application written using this approach is guaranteed to be good. Nothing like this.
I note that the described approach is workable, clearly structured, easily supported and, in one word: a worker!
What does complex application mean?
When you operate a Viewport object with a BorderLayout, a grid table and a form in one file, this is, of course, not a complicated application, right? If you have dozens of windows, each with a grid-table, a form or a BorderLayout and all this stuff is scattered across dozens of files, then this is already a complex and large application, right?
There is one sweet word in German: Jein = Ja + NeinThe answer to both of these statements will be
Jein . The question is: when does the application become large and complex? The answer is simple: at the very moment you begin to feel it as such. This is the moment when it becomes difficult to navigate a large number of files, or problems begin when searching for a particular place if you try to understand the relationship of components, for example, and so on.
It is safe to say that every application is as difficult as simple to be well-written and can become really great as soon as we start adding new functionality, increasing the amount of code, adding CSS rules, etc.
The best and safest installation when creating a new application is - “I am starting a complex application!”
Files and directories
What needs to be organized first. At our disposal there is always a DocumentRoot directory so that all the subdirectories mentioned below will be listed relative to it.
Recommended directory structure:
- ./css (optional link)
- ./ext (link)
- ./img (link)
- ./js
- index.html
The word "link" means that the directory is a soft link to the real directory where the files are located. The advantage of this technique is that, for example, you can load a new version of Ext into any real directory and make the link point to it, which will save you from editing paths in your code. You can test the new version and if everything is in order, leave the link pointing to the new version, and if not, just return it.
- css is the repository of all your styles. If you have global styles, like company colors or font designs, then you can also create this directory as a link;
- ext - a link to the version of Ext you are using, as described earlier;
- img - directory with your images. It may also contain subdirectories for icons, etc .;
- js - will contain all JavaScript files of the application, as well as their assembled version;
- index.html - HTML file that is the entry point of your application. You can name it as you like, and there can be several html files, for example, for an authentication operation. But in any case, the input point file (with the onReady handler) must be one;
- Additionally, you can create a directory or a link to the server side of the application (./classes in my case). You can give her any name you like, but you should choose consistent with all the applications you are developing (the names ./server, ./php will be good options).
index.html
The minimum content of
index.html can be as follows:
<html>
<head>
<meta http-equiv = "Content-Type" content = "text / html; charset = utf-8">
<link rel = "stylesheet" type = "text / css" href = "./ ext / resources / css / ext-all.css">
<link rel = "stylesheet" type = "text / css" href = "./css / application.css">
<script type = "text / javascript" src = "./ ext / adapter / ext / ext-base.js"> </ script>
<script type = "text / javascript" src = "./ ext / ext-all-debug.js"> </ script>
<script type = "text / javascript" src = "./ application.js"> </ script>
<title> A Big Application </ title>
</ head>
<body> </ body>
</ html>
Although you can work with a file like the one above, I recommend adding header information both to this type of file and to all others. The end of file marker also matters. See
examples of these kind of headlines.
js / application.js
We need a file where we can put an onReady handler. Let its name be
application.js . The minimum content of such a file is shown below:
// vim: sw = 4: ts = 4: nu: nospell: fdc = 4
/ **
* An Application
*
* @author Ing. Jozef sakalos
* @copyright (c) 2008, by Ing. Jozef sakalos
* @date 2. April 2008
* @version $ Id $
*
* @license application.js is licensed under the terms of the open source
* LGPL 3.0 license. Commercial use is prohibited to the extent that the
* code / component (s)
* licensed development library or toolkit without explicit permission.
*
* License details: http://www.gnu.org/licenses/lgpl.html
* /
/ * global Ext, Application * /
Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';
Ext.ns ('Application');
// application main entry point
Ext.onReady (function () {
Ext.QuickTips.init ();
// code here
}); // eo function onReady
// eof
Your code may be different, but it is necessary to set
Ext.BLANK_IMAGE_URL to a value that refers to your server. This is the path to a transparent 1x1 image that is used by Ext as a placeholder and if it leads to a void, you may encounter various drawing problems such as: the lack of an arrow in
Ext.form.ComboBox , icons, etc.
You may also need to create a global variable for your application (in this case,
Application ).
What you need to be sure of is that the onReady handler is present only once - at the entry point to the application.
css / application.css
Put all your styles in this file, if you have them. If you need only a small number of those, then it may not make sense to create a separate file for them. You can write them directly to a document using
.
On the contrary, remember that you are creating a complex application, therefore, everything has its place. If you write styles in the title of the document, then you will sooner or later have to solve problems with drawing and you will not know which styles prompted them.
How not to do
What usually follows how a certain basis was obtained, such as we have at this stage? Start writing code. So, we plunged into the chair and began to create:
var vp = new Ext.Viewport ({
layout: 'border'
, items: [
new Ext.grid.GridPanel ({
store: new Ext.data.Store ({
proxy: new Ext.data.HttpProxy ({...
One minute. Developing this, we will very soon have all 10,000 lines of code in
application.js , and this is the last thing we need. Obviously, some stage was missed. If we created such a huge file, why don't we paste its code directly into
index.html ?
The right way: divide and conquer
Any integer, regardless of its size, consists of smaller systems, which, in turn, consist of even smaller parts containing some elements. Your complex application being developed is no exception. And now is the time to determine for yourself these parts, components and connections between them.
So, sit down even more comfortably, think carefully, draw a sketch, make a list, it doesn't matter what you do, the main thing is that as a result you have a list of components that your application will consist of. At least the main ones.
Pre-configured classes
Well, as soon as you are done with the analysis and determination of the components of your application, you can start writing one of them. What is the best way to do this? The best solution would be to write classes that extend standard Ext components, since the latter already have all the settings rewritten by the values ​​passed to their constructors. I call these extensions pre-configured classes because they rarely introduce new features and are mainly used for configuration. An example would be the “Personnel” grid table with its model of columns, storage, sorting settings, editors, etc.
In this case, the configuration of our window could look like this:
var win = new Ext.Window ({
title: 'Personnel'
, widht: 600
, height: 400
, items: {xtype: 'personnelgrid'}
});
win.show ();
Writing a pre-configured class
We will understand by example:
Application.PersonnelGrid = Ext.extend (Ext.grid.GridPanel, {
border: false
, initComponent: function () {
Ext.apply (this, {
store: new Ext.data.Store ({...})
, columns: [{...}, {...}]
, plugins: [...]
, viewConfig: {forceFit: true}
, tbar: [...]
, bbar: [...]
});
Application.PersonnelGrid.superclass.initComponent.apply (this, arguments);
} // eo function initComponent
, onRender: function () {
this.store.load ();
Application.PersonnelGrid.superclass.onRender.apply (this, arguments);
} // eo function onRender
});
Ext.reg ('personnelgrid', Application.PersonnelGrid);
What is going on here? We extend
Ext.grid.GridPanel by creating a new
Application.PersonnelGrid extension class and registering a new xtype for it with the name of
personnelgrid .
In fact, we transfer to the ordinary grid-table all the settings that are sufficient to turn it into a specialized “Personnel” grid-table. From now on, we have a new component, the building block of our application, which we can use anywhere (in the window, on the panel, on our own) to display the list of employees. You can create it as follows:
var pg = new Application.PersonnelGrid ();
or using xtype (the so-called lazy creation):
var win = new Ext.Window ({
items: {xtype: 'personnelgrid'}
....
});
Organization and storage of pre-configured classes
The code above does not need, and will not run in, the onReady handler — it does not operate on the DOM, but simply creates a JavaScript object. Therefore, it can and should be placed in a separate file (
js / Application.PersonnelGrid.js ) and will be included in the
index.html header.
Well, as long as everything goes well - we have almost everything ready and all (almost) is that we need to continue to describe the pre-configured classes, put them in ./js, include in
index.html and build our application from their instances as pieces puzzles.
Looks good, huh?
Interconnect
Imagine that you need a border layout with a list of links to the left (west region) and a bookmark panel in the middle (center region). Clicking the link should create a new bookmark in the center. Where do you put the logic of everything that happens, the event handler and the creation code? Left or center?
Nowhere. Why? If we have a pre-configured class that creates and displays the list on the left, and we put the logic there, then its existence loses its meaning without a central region. We simply cannot use the list without the bookmarks bar.
If we place the logic in the central area, the result will be similar: the bookmarks panel cannot exist without a list of links.
There is only one component aware of the existence of the left and center panels - this is their container with frame layout, the only correct place to place the intercomponent logic.
Production system
Due to the agreement on the organization of our application, very early we will encounter a large number of JavaScript files (in my case, about 80 and their number is growing every day), which can adversely affect the performance of a really working, not a test, system.
')
The best solution is to merge (concatenate) all JavaScript files in the desired order. The result will be one large file, which must then be compressed with one of the tools for minification or compression.
The production system will connect:
- ext-all.js
- app-all.js
- application.js
Additional information on compressing your code as well as creating build files can be found in
another guide .
Conclusion
In general, this is all ... There are specialized techniques for some classes of Ext, many other server and client chips, but what was stated above is a general concept.
Happy coding!
As a translator:
- The article caught me by describing the general concept of working with a complex application in a particular development case in ExtJS;
- further translation will be placed in the official manual of the project next to the original , so please respond not only to the pros and cons, but also in text form, please;
- The seemingly strange dance around links when describing a file organization is due to the fact that ExtJS developers themselves intensively use the construction of builds from multiple build files. In this case, the new version of the same ExtJS is both the entire source tree and the build of the framework. It is much more convenient, of course, to change the link than to copy many files back and forth.