|
|||||||
![]() |
|
|
Thread Tools |
|
#1
|
|||
|
|||
|
I'm rather new to Ext, and advanced JavaScript use. I've mainly used JavaScript sparingly to manually validate HTML forms, or do some other simple action. As for my programming experience, I've been using PHP for a while, and recently made the jump to PHP5, requiring a better understanding of true OOP, although I've read that PHP5 is not quite there.
I hate to beat the application design 'dead horse' here, although I think the horse is still limping along. Perhaps I'm not looking in the right place. I've read through the following forum posts so far, which cover or touch on the issue of app design: Advice needed on structuring application code Variable Placement? Controlling Memory Usage. Application Design Patterns Besides the forum, I also read the "Application Layout for Beginners" in the manual. I'm creating an application that will run on an intranet. I'll be using PHP5 in the backend with the Zend Framework, and Ext for the frontend, effectively replacing the 'View' of the Zend Frameworks MVC concept. The PHP backend will simply dish out data in the proper format to Ext as requested. But how I should design the Ext part of the application is still a mystery to me. While I understand the Module Pattern concept, I'm still not sure how to properly lay everything out in my application. For instance, I have the following code in my test app: test.js // create namespace
Ext.namespace('TEST');
// create a data module
TEST.data = function() {
// test grid data
var gridData = [
['9/1 12:00am', 'chughes', 'testing'],
['9/2 12:00am', 'ksmith', '1..2..3...'],
['9/3 12:00am', 'pjames', 'hello'],
['9/4 12:00am', 'ajones', 'another test'],
['9/5 12:00am', 'pkramer', 'data'],
['9/6 12:00am', 'rsmith', 'more data']
];
return {
storeGridData: new Ext.data.SimpleStore({
fields: [
{name: 'created', type: 'date', dateFormat: 'n/j h:ia'},
{name: 'author'},
{name: 'subject'}
]
}),
loadGridData: function() {
this.storeGridData.loadData(gridData);
}
};
}();
// create a panels module
TEST.panels = function() {
return {
panelAccordionNavigation: {
title:'Navigation',
html:'nav goes here',
border:false
},
panelAccordionSettings: {
title:'Settings',
html:'settings go here',
border:false
},
panelTabWelcome: {
html:'<p>This is a welcome tab.</p>',
title: 'Welcome',
style:'padding:10px',
autoScroll:true
},
panelTabAnother: {
title: 'Another Tab',
html: '<p>This is another tab.</p>',
autoScroll:true,
closable:true
},
panelTabGrid: new Ext.Panel({
title: 'Grid Tab',
autoScroll:true,
closable:true,
listeners: {
'activate': function(p) {
TEST.data.loadGridData();
p.doLayout();
},
single:true
}
}),
gridpanelTickets: new Ext.grid.GridPanel({
store: TEST.data.storeGridData,
columns: [
{header: "Created", width: 75, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'created'},
{header: "Author", width: 75, sortable: true, dataIndex: 'author'},
{id: 'Subject', header: "Subject", sortable: false, dataIndex: 'subject'}
],
stripeRows: true,
autoExpandColumn: 'Subject',
border:false,
autoHeight:true
}),
tabpanelMain: new Ext.TabPanel({
border:false,
activeTab:0
}),
init: function() {
this.panelTabGrid.add(this.gridpanelTickets);
this.tabpanelMain.add(this.panelTabWelcome);
this.tabpanelMain.add(this.panelTabAnother);
this.tabpanelMain.add(this.panelTabGrid);
}
};
}();
// create a layout module
TEST.layout = function() {
return {
// setup the north region
regionNorth: {
region:'north',
html: 'North',
border: false,
baseCls: 'x-plain',
height: 75,
margins:'5 5 0 5'
},
// setup the east region
regionEast: {
region:'east',
html:'east side',
title: 'East',
width:200,
margins:'5 5 0 0'
},
regionSouth: {
region:'south',
html:'south side',
title: 'South',
collapsible:true,
minHeight:100,
maxHeight:200,
height:100,
split:true,
margins:'0 5 5 5'
},
regionCenter: {
region:'center',
layout: 'fit',
margins:'5 5 0 5',
items: TEST.panels.tabpanelMain
},
regionWest: {
region:'west',
title: 'Navigation',
width:150,
margins:'5 0 0 5',
layout:'accordion',
layoutConfig:{
animate:true
},
items: [
TEST.panels.panelAccordionNavigation,
TEST.panels.panelAccordionSettings
]
},
// render the main application layout
renderMainLayout: function() {
// init the panels module
TEST.panels.init();
new Ext.Viewport({
layout: 'border',
items: [
this.regionNorth,
this.regionEast,
this.regionWest,
this.regionSouth,
this.regionCenter
]
});
}
};
}();
// create application module
TEST.app = function() {
return {
// init method
init: function() {
// render the main layout
TEST.layout.renderMainLayout();
}
};
}(); // end of app
// end of file
I'm not sure why the array of pre-defined item configs in a TabPanel throws an error, but not a Panel with an 'accordion' layout. (see above code: 'regionWest' in the layout module) I can only assume that I just don't know what's happening in the background. Enough with my problems and on to the issue at hand. Is this design a good one, or has someone come up with something better? As for components creation goes, should I define all of my components in a JavaScript file as a module and make calls to them as needed? Or, should I just 'serve' the components to Ext with PHP using Ajax? And, one final question pertaining to efficiency(whew): Does defining a new component as an actual component (new Ext.Component) create a bigger overhead than a simple JSON config? Thanks so much. |
|
#2
|
|||
|
|||
|
Thanks for posting this. I'm in very similar boat. I've been learning from the ext examples/demos which kind of have a procedural vs. OOP flavor I think. I was just about to post a very similar thread.
In addition to your questions I was also wondering about private properties. For the most part I've noticed most of the properties you've created are public. The only private property I noticed was the underlying data. So, my question is, what would be considered good practice for determining what should be public vs. private? As I convert my "procedural" example code I have been working with to OOP style like you have, I almost find it a chore to deal with the scope when anything is private. So as I hack through the code I'm left wondering why make anything private? These are not "classes" per se correct? So is there really any issues with worring about making things private so they are not inherited or however that whole inheritance thing works? Edit: One other issue that's been in the back of my mind is how to deal with file structure. That is, with all of these modules do you develop individual js files for each module or lump them into one file? For example I see that ext/source breaks up the files into modules. And then there's ext_all.js which I presume is basically a synthesis of the individual source files. I've read that web pages serve up quicker with fewer/bigger files than more/smaller files. So, if all of that is correct, is there some utility that helps to combine your files once you go from development to production? |
|
#3
|
||||
|
||||
|
I successfully use Ext.App (with slightly modified init process) from ext/examples/desktop for a huge application I write currently. I follow the following rules while writing:
1. Use lazy instantiation (xtype) as much as possible. The point here is that if you use xtypes the real Ext objects they represent are not even created until they are needed. We've already got used to lazy rendering (render only when needed) but Ext 2 makes a step forward: xtype = if you will need this object then this is how it will be created. 2. Use pre-configured classes. xtype approach described in point 1. is only possible if you have "pre-configured classes" what are extensions of Ext classes with configuration options applied and/or with added functionality. For example, I use the following code for gender selection combo:
Imagine you have a border layout with grid in west and form in center. Selecting a grid row should display values in form. Now, where to put logic of that? To grid or to form? Neither of them. Grid doesn't know that form exists and form doesn't know that grid exists. The component that is aware of both of them is their common parent (viewport or window). Therefore, the relations have to be established at the parent level, e.g. window. Code there listens to grid's events and loads form data on selection change and on form submit event it updates grid record. If I'd put this code to grid the grid cannot exist w/o form, if to form, form cannot exist w/o grid. Got the idea? 4. Keep each class in its own file while developing, concat and minify for production. Yes, this is Ext approach. I just take all files I include in the header of devel page, concat 'em (in the original order) to one file, minify the result and I have production version. A final advice: Don't speculate too much about application structure, layout, various controllers, loaders, interfaces, whatever too much. Write good re-usable pre-configured classes instead and put them somehow together in the first place. If they are really good and re-usable you can change your app layout, use a different approach and your classes will still work. Like Lego - if you have blocks you can build a castle in minutes.
__________________
Jozef Sakalos, aka Saki A lot of valuable info at: Saki's Extensions and Plugins Saki's Extensions and Plugins Docs Saki's Examples, Latest: Grid in Card Layout Saki's Blog, Featured: Writing a Big Application in Ext, Latest: What the hell is mon and mun? |
|
#4
|
||||
|
||||
|
I use a lot of ajax to load ext "modules / classes" into a main layout. This seems to make things load a lot quicker. So say I had a main layout with buttons like add item, contact, etc each of these buttons would load the module required to supply the fuctionality - this could added in tabs or popup windows.
Not only does everything run faster, it also keeps things organised as each of my modules reside in their own files. Some of the apps I have worked on are so large that it would mean a multiple mb download if everything was in the one file! The main thing is to have a good server side framework operating behind this. -Lobos |
|
#5
|
||||
|
||||
|
Yes, this is the approach I was also thinking of when application size reaches some limit or when I hit a performance barrier.
I would basically add point 0 to the above rules that would read 0. Lazy load and would drop point 4, concatenation part.
__________________
Jozef Sakalos, aka Saki A lot of valuable info at: Saki's Extensions and Plugins Saki's Extensions and Plugins Docs Saki's Examples, Latest: Grid in Card Layout Saki's Blog, Featured: Writing a Big Application in Ext, Latest: What the hell is mon and mun? |
|
#6
|
|||
|
|||
|
Saki
Seems a little different than your application layout for beginners tutorial. Or would you still use the essence of that layout but reference your preconfigured classes? Maybe your comments here have the makings for the follow up tutorial on the subject. Are there utilities for concatenating/minimizing/compressing files automatically? |
|
#7
|
||||
|
||||
|
Quote:
__________________
3.x - ( Docs | Examples | SVN Log ) / 2.x - ( Docs | Examples ) HOWTO - ( Report Bugs | Post Proper Code ) / Learn / Saki's Examples Forum Search (FF/IE plugin) / API Search (FF/IE plugin) |
|
#8
|
||||
|
||||
|
The title of the tutorial says Application Layout for Beginners so I'd expect that one application singleton would do for small application of the beginners. One singleton is just not enough for larger applications that doesn't invalidate in any means it's design or usability for smaller ones.
Well, I would maybe say that these are general good rules that work for me, however, I do not want to "prescribe" a layout of application for more advanced users. There are many situations that require different approaches. Nevertheless, the rule write good reusable pre-configured classes is really an universal one. I use linux, so concat tool is a part of it (cat file1 file2 file3 ... > file-result). There is source code of jsmin (jsmin.c) by Douglas Crockford hanging around on internet - just google for it. Compiling (on linux) is as easy as: cc jsmin.c -o jsmin
__________________
Jozef Sakalos, aka Saki A lot of valuable info at: Saki's Extensions and Plugins Saki's Extensions and Plugins Docs Saki's Examples, Latest: Grid in Card Layout Saki's Blog, Featured: Writing a Big Application in Ext, Latest: What the hell is mon and mun? |
|
#9
|
|||
|
|||
|
Thanks for your pointers.
Quote:
Quote:
I've read up more on different styles of OOP. I guess I'm trying to tap into the experience of someone more experienced as to what they do rather than reinvent the wheel in a sense. |
|
#10
|
|||
|
|||
|
Quote:
Would you have a small snippet of code or example? This is all interesting stuff. Please keep elaborating, I might just learn something! ![]()
__________________
Thanks! Chuck
|
![]() |
| Thread Tools | |
|
|