I usually advocate for having as much configuration as possible in class config options, because it reads better and is easier to override in subclasses. Besides that, there is a strong possibility that in future Sencha Cmd will have optimizing compiler so if you keep your code declarative, it could benefit from optimizations.
Compare:
Ext.define('MyPanel', {
extend: 'Ext.grid.Panel',
initComponent: function() {
this.callParent();
this.store = new Ext.data.Store({
fields: [ ... ],
proxy: {
type: 'direct',
directFn: Direct.Store.getData
}
});
this.foo = 'bar';
}
});
...
var panel = new MyPanel();
And:
Ext.define('MyPanel', {
extend: 'Ext.grid.Panel',
alias: 'widget.mypanel',
foo: 'bar',
store: {
fields: [ ... ],
proxy: {
type: 'direct',
directFn: 'Direct.Store.getData'
}
}
});
...
var panel = Ext.widget({
xtype: 'mypanel',
foo: 'baz'
});
Note how these approaches are very different. In the first example, we're hardcoding a lot: object property values, store configuration, MyPanel class name when it's used; we're practically killing the idea of a class because it becomes inextensible. In the second example, we're creating a template that can be reused many times with possibly different configuration - basically, that's what the whole class system is about.
However, the actual difference lies deeper. In the first case, we're effectively deferring class configuration until runtime, whereas in the second case we're defining class configuration and applying it at very distinctively different phases. In fact, we can easily say that the second approach introduces something JavaScript lacks natively: compile time phase. And it gives us a plethora of possibilities that are exploited in the framework code itself; if you want some examples, take a look at Ext.app.Controller
and Ext.app.Application
in latest 4.2 beta.
From more practical perspective, the second approach is better because it's easier to read and deal with. Once you grasp the idea, you will find yourself writing all your code like that, because it's just easier this way.
Look at it this way: if you would write an old style Web application, generating HTML and stuff on the server side, you would try not to have any HTML mixed with the code, would you? Templates to the left, code to the right. That's practically the same as hardcoding data in initComponent
: sure it works, up to a point. Then it becomes a bowl of spaghetti, hard to maintain and extend. Oh, and testing all that! Yuck.
Now, there are times when you need to do something with an instance at runtime, as opposed to a class definition time - the classical example is applying event listeners, or calling control
in Controllers. You will have to take actual function references from the object instance, and you have to do that in initComponent
or init
. However, we're working on easing this problem - there should be no hard requirement to hardcode all this; Observable.on()
already supports string listener names and MVC stuff will too, shortly.
As I said in the comments above, I'll have to write an article or guide for the docs, explaining things. That would probably have to wait until 4.2 is released; meanwhile this answer should shed some light on the matter, hopefully.