One of the most appealing features of Ext JS 4 is the fact that it has all you need to develop your application using the MVC architecture. You don’t need to add any third party MVC framework to your Ext JS application. In your controllers, that you attach to the application, you simply declare the class names for your store and a view. In return, Ext JS generates the controller’s getter methods to access the store and view instances and also allows controllers to intercept events that may happen anywhere inside the views. You are not forced to use MVC, but since it is convenient and does not cost much. I just finished preparing a 100% MVC sample for the upcoming release of the Ext JS version of our Clear Data Builder code generator.
Convention over configuration is the only price you pay for implementing MVC in your application. Just follow the strict folder names – controller, view, store, model. It’s not too expensive, is it? In fact, I like it.
That said, dare you to name a store class as MyApp.store.CustomerStore Ext leaves you one on one with eyebrow-raising controller code like this.getCustomerStoreStore()
. In other words, Ext is appending the Store suffix for stores, Model for models and so on, softly suggesting that you should stay away from using your own suffixes.
Now, if you are anything like me, you get an instant acid reflux at multiple classes with the same core name like MyApp.model.x.y.z.Customer, MyApp.store.x.y.z.Customer, and, perhaps, MyApp.controller.x.y.z.Customer and others, especially when you jump between them in one editor. Do not worry – all you need to treat the “condition” is to override the createGetters
method of the Ext.app.Controller before your application starts, for instance – this way:
//app.js
Ext.Loader.setConfig({
enabled: true
});
Ext.require(
['Ext.app.Controller'],
function () {
Ext.app.Controller.override({
createGetters: function(type, refs) {
type = Ext.String.capitalize(type);
Ext.Array.each(refs, function(ref) {
var fn = 'get',
parts = ref.split('.'),
pos;
// Handle namespaced class names. E.g. feed.Add becomes getFeedAddView etc.
Ext.Array.each(parts, function(part) {
fn += Ext.String.capitalize(part);
});
// --- Prevent StoreStore-like suffixes ---
pos = fn.length - type.length;
if (pos<=0 || fn.substring(pos)!==type) {
fn += type;
}
if (!this[fn]) {
this[fn] = Ext.Function.pass(this['get' + type], [ref], this);
}
// Execute it right away
this[fn](ref);
},this);
}
});
// --- Start your application when done
Ext.application({
name: 'MyApp',
controllers: [
'MainController'
],
autoCreateViewport:true
});
}
);
To learn more about the proper way of architecting enterprise applications attend our 2 day Flex-to-ExtJs workshop on April 19-20, 2012. Enter Victor as a promo code to get $100 off the price.
Victor
UPDATE: See our post Why and How to use Ext JS Overrides that illustrates the most elegant Ext JS overriding technique.