Layout
Views basically work as is, because that is how ExtJS was designed. Any subclass of a UI widget will work as a view. However, to make the concept of a view work well they should only be instantiated once and have their modification logic in a controller. For this reason I recommend using the following directory layout:
- app.js
- ext/
- app/
- controllers/
- Controller.js
- ContentController.js
- lib/
- view/
- layout/
- Content.js
- Viewport.js
- OtherView.js
app.js
This should just a Ext.onRead function that instantiates the Viewport.js class. It should also setup any globals that will be used throughout the app and should be included last.
lib/
Since views should only be instantiated once this is the place to put reusable code. Items here will not usually have an xtype because they will be extended by view items.
Controller.js
This is the base class for all controllers. It has the helper to bind to views and look them up afterwards. A small override to Ext.ComponentMgr is required to make everything work.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ext.ComponentMgr.singletons = {}; | |
Ext.ComponentMgr.create = function(config, defaultType){ | |
if(config.render){ return config; } | |
var item = new Ext.ComponentMgr.types[config.xtype || defaultType](config); | |
if(item.xtype){ | |
Ext.ComponentMgr.singletons[item.xtype] = item; | |
} | |
return item; | |
}; | |
Ext.create = Ext.ComponentMgr.create; | |
App.controller.Controller = Ext.extend(Ext.util.Observable,{ | |
constructor: function(config){ | |
App.controller.Controller.superclass.constructor.apply(this,arguments); | |
this.controls = {}; | |
if(this.init){ | |
this.init(); | |
} | |
}, | |
//<classname>: { | |
// <listeners config=""> | |
//} | |
control: function(hash){ | |
Ext.iterate(hash,function(key,value){ | |
var item = eval(key); | |
Ext.util.Observable.observeClass(item,value); | |
},this); | |
}, | |
getComp: function(item){ | |
return Ext.ComponentMgr.singletons[item]; | |
} | |
}); |
Content.js
This needs to be a simple card layout so that you can add new items to it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
App.view.layout.Content = Ext.extend(Ext.Panel,{ | |
layout: 'card', | |
layoutConfig: {deferredRender: true}, | |
items: [{html: 'first card'}], | |
activeItem: 0, | |
defaults: { | |
border: false | |
}, | |
showCard: function(card){ | |
var idx = this.items.findIndex('xtype',card); | |
this.getLayout().setActiveItem(idx); | |
} | |
}); | |
Ext.reg('content',WebUI.view.layout.Content); |
ContentController.js
This class binds to a something that would change the content panel, like a TreePanel, and then using Ext.ComponentMgr creates a card, adds it to the content, and shows it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
App.controller.NavController = Ext.extend(App.controller.Controller,{ | |
init: function(){ | |
this.control({ | |
// Tree panel that changes the content when nodes are clicked | |
'App.view.layout.Nav': { | |
click: this.navClick, | |
scope: this | |
} | |
}); | |
}, | |
navClick: function(node,e){ | |
if(!node.leaf){return;} | |
// We use the id of the node as the xtype to create and add | |
var content = this.getComp('content'); | |
var item = this.find_or_create(node.id,content); | |
content.showCard(node.id); | |
}, | |
find_or_create: function(xtype,content){ | |
var item = this.getComp(xtype); | |
if(!!item){ | |
if(Ext.ComponentMgr.isRegistered(xtype)){ | |
var item = Ext.ComponentMgr.create({xtype: xtype},xtype); | |
content.add(item); | |
} | |
} | |
return item; | |
} | |
}); | |
new App.controller.NavController(); |