ExtJs5: Call Controller 2's method from Controller 1

DarkKnightFan picture DarkKnightFan · Jun 16, 2014 · Viewed 7.5k times · Source

I am trying my hands on the new ExtJs 5. I have created a small app as per the defined MVC pattern of ExtJs5.

Am using ViewControllers for each View.

Problem Statement: Now suppose I have two VCs (Controller1 & Controller2). Each has its own methods. I wish to call a method of Controller2 from Controller1. I want to update the View associated with the Controller2 from Controller1.

E.g. Suppose there is a separate view for Status Bar and a ViewController(StatusBarController). 
This VC has a method to update the view based on whatever message it receives as input parameter. 
All the other controllers in the application will call this VCs method to update the status of the application on the status bar.

In the previous versions, this.getController('StatusBarController') was used to get the handle to any controller and then call its method.

But this is not working in my case when I use a ViewController.

Can anyone guide me how to achieve this thing? And also whether it is the correct/ideal way to do such a thing or is there any better option?

Here is my code:

StatusBarView:

Ext.define('MyApp.view.statusbar.StatusBarView', {
extend : 'Ext.panel.Panel',
controller: 'StatusBarController',
region : 'south',
xtype : 'status-bar-panel',
html : 'This is a status bar'
});

StatusBarController:

Ext.define('MyApp.controller.StatusBarController', {
extend : 'Ext.app.ViewController',
alias: 'controller.StatusBarController',
updateStatusBar : function(message) {
    this.getStatusBarView().update(message);
}   
});

Some Other Controller in app:

Ext.define('MyApp.controller.ResourcesPanelController', {
extend : 'Ext.app.ViewController',
alias : 'controller.ResourcesController',
onItemClick : function(tree, record, item, index, e, eOpts) {
            // here I am calling the other controller's method.
    this.getController('StatusBarController').updateStatusBar(
            record.data.text + ' has been clicked');
}
});

Answer

Saki picture Saki · Jun 16, 2014

ViewControllers are tightly related to their views, they are even created and destroyed together with views, and they should be controlling only their own views. The idea is to separate logic from UI on the view level.

Calling methods of one ViewController from another is not a good practice and, for big applications, it is route to hell as it inevitably leads to unmaintainable spaghetti code.

The correct approach is minimize the number of ViewModels, ViewControllers and Controllers and let them work in their own areas of responsibilities.

For example: Suppose you want a grid and form in a container. Form would allow editing of the record selected in the grid. Plus some buttons. These three views (container, grid and form) together form a unit. Thus:

  1. only one ViewController at container is needed, all views can use it
  2. only one ViewModel at container is needed, all view can use it
  3. if you want to let this trio to communicate with the outer world of the rest of the application, the container's view controller can fire events and can have API methods to call

Thus, if needed, you can have an MVC (global) Controller(s) that would coordinate functions of units, like our trio.

Also, data binding simplifies the logic to a great degree so controllers and listeners are not needed that much.

See Binding Grid and Form in ExtJS 5 example.