Managing Events with Ext JS 4.X
One of the challenges with creating a large single page
application with Ext JS 4.X is Event Management. Each click event of the view
needs to be (or usually is) wired up in the controller class method. If your
controller manages several views, this can lead to a lot of event wiring.
With the Ext JS 4.x framework, there are several ways to
wire up your events. The two that I see
the most of are:
1
1 1) In
the controllers init function, a call to the this.control({}) method is used
with the component’s selector to wire up its event to the event handler.
'containerAlias > container
button[name=search]': {
click: this.onCustomerSearch
},
'containerAlias2
container[name=controls] button[name=someaction]':
{
click: this.onSomeAction
},
'containerAlias >
container button[name=save]': {
click: this.onSave
},
'someAliasName button[action=close]': {
click: this.onClose
},
'SomeAliasName button[name=cancelMe]': {
click: this.onCancel
},
... (continues…)
The biggest issue I’ve have with using this pattern is
that this method call get very, very, very long. As the number of components in a view or views
increase, this method call gets longer and longer. Also, if the view structure changes, you usually
have to come back to change the selectors. This can be time consuming,
depending on how many components and events you have.
See the Sencha docs for more information on control method
in the Controller class:
2 2) Another way is to query the container in afterrender
event handler and to get each component wired up.
OnContainerRender: function (container) {
Var searchBtn = container.down('button'),
addBtn = searchBtn.next(),
saveBtn = addBtn.next(),
editBtn = saveBtn.next(),
isActive = container.down('checkbox'),
grid = container.down('grid');
searchBtn.on('click', this.onSearch, this);
addBtn.on('click', this.onAdd, this);
saveBtn.on('click', this.onSave, this);
editBtn.on('click', this.onEdit, this);
isActive.on('change',this.onIsActiveChange, this);
grid.on('select', this.onGridSelect, this);
},
Again; if the container structure changes, you may have
to change the components selector in the up and down methods. For example if the you added another button
before the search button, you would have to change the container.down('button'), to container.down('button').next();.
See the Sencha docs for more information on up and down method of the
Element class and the
afterrender event:
Lately
I’ve been working with the idea of just having the view expose the events you
want to wire up in the controller. This pattern cuts down on the amount of code
in the controller and it makes managing of view changes easier.
In
the view, override the initComponent method and expose the events with the
addEvent method
Step 1:
initComponent:
function () {
this.addEvents({
save: true,
close: true,
select: true,
});
this.items = this.createItems();
this.callParent(arguments);
},
See the Sencha docs for more information on the
initComponent and addEvents methods
Step
2:
In the
view definition, wire up the components events in the listeners object and have
the handler fire the views corresponding event.
//me
is a variable to the view (var me = this;)
{
text: 'Save',
listeners: {
click: function (btn, e) {
me.fireEvent('save', me); //calls the view level event
}
}
},
... Grid definition
listeners:
{
select: function (grid, record, index, e) {
me.fireEvent('select', me, record,
index); //calls the view level event
}
}
Notice
that you can tailor the arguments that are handle by the view event listener. You
can add or cut down the number of arguments needed
See
the Sencha docs for more information on the listeners object http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.util.Observable-cfg-listeners
Step
3:
In
the controller, wire up the events on the view.
This.control({
'AliasNameForView’: {
save: this.onSave,
close: this.onClose,
select: this.onQQSelect
}
});
See the Sencha docs for more information on control method in the
Controller class:
The
benefits with this pattern are as follows:
1 1) Instead of having to wire up each component
separately outside the view, it allows for the isolation of the events to the
view itself.
2 2) The amount of code in the controller to wire up the events is cut
down.
3 3) If the structure of the view changes, the code in the controller
to wire the event does not have to change.
This allows for better code management.
As we start creating more and more “Single Page
Applications” (SPA) web applications and move more business login to the client
site, we have to work on better JavaScript code management. These applications will get very large and we
all know that applications change throughout their existence. More we can do to
manage the code better will benefit us in the long run.