Page 1 of 3 123 LastLast
Results 1 to 10 of 25

Thread: ExtJs5: Call Controller 2's method from Controller 1

  1. #1

    Default ExtJs5: Call Controller 2's method from Controller 1

    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:

    Code:
        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:

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

    Code:
        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');
        }
        });

  2. #2
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,664
    Answers
    512
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid MultiSearch Plugin, Grid MultiSort Plugin, Configuring ViewModel Hierarchy


  3. #3
    Sencha User
    Join Date
    Apr 2010
    Posts
    85
    Answers
    3

    Default

    Let's say all the views are created at application load. Also, the main view (viewport) will never be removed. Do you think it's better to have a global MVC Controller listening to component events and coordinate views, or is it better to communicate between ViewControllers with controller events? We can basically do everything that global MVC Controller does in MainViewController, right? Then we can fire someevent in ViewController1 and then listen to it in MainViewController or even in ViewController2.

    But I see in examples, that Sencha team often uses global MVC Controllers.

    What is the best practice to communicate between ViewControllers?

  4. #4
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,451
    Answers
    3997

    Default

    I personally use ViewControllers as much as I can, my MainViewController even listens to the routes but that's the UI my application uses where Main view can show all the views. The issue with ViewController is they may not be instantiated when an event occurs, just depends how your application is architected. If your Main view is always instantiated and it's ViewController will then be too then that is the place to catch all things but if you have child views with ViewControllers and that view is added/removed on the fly is where you can get into trouble so just be smart about how you do things.

    For cross controller communication, this works the same for ViewControllers as well as the global Controllers. If you fire an event on a controller, you can use the controller event domain to listen to events. For example if one controller fires an event like this:

    Code:
    Ext.define('MyApp.view.foo.BarController', {
        extend : 'Ext.app.ViewController',
        alias : 'controller.myapp-foo-bar',
    
        onSomething : function() {
            this.fireEvent('something', this, 'blah');
        }
    });
    Then any controller (view or global controller) can listen to it in the same way:

    Code:
    Ext.define('MyApp.controller.Baz', {
        extend : 'Ext.app.Controller',
    
        listen : {
            controller : {
                '*' : {
                    something : 'onSomething'
                }
            }
        },
    
        onSomething : function(controller, blah) {
        }
    });
    Mitchell Simoens @LikelyMitch
    Modus Create, Senior Fullstack Engineer
    ________________
    Modus Create is based on the model of an open source team. We’re a remote, global team of experts in our field. To find out more about the work we do, head over to our website.

    Check out my GitHub:
    https://github.com/mitchellsimoens

  5. #5
    Sencha User
    Join Date
    Apr 2010
    Posts
    85
    Answers
    3

    Default

    Thanks for your answer Mitchell.

    When you think about it, it all makes sense. View, ViewModel and ViewController together form a Unit that is independent from other Units, but can communicate with them via controller event domain.

  6. #6
    Sencha User
    Join Date
    Apr 2010
    Posts
    85
    Answers
    3

    Default

    And normal MVC controllers can be used kinda like a service

  7. #7
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,451
    Answers
    3997

    Default

    Yes, a View, ViewModel and ViewController can be thought of as one widget entity. I'm currently rewriting the support portal and I don't have a global controller, everything is done in ViewControllers, my MainViewController acts as the global operator but that's because the UI is quite simple.
    Mitchell Simoens @LikelyMitch
    Modus Create, Senior Fullstack Engineer
    ________________
    Modus Create is based on the model of an open source team. We’re a remote, global team of experts in our field. To find out more about the work we do, head over to our website.

    Check out my GitHub:
    https://github.com/mitchellsimoens

  8. #8

    Default Managed it with a global controller

    Well as suggested in the earlier answers I managed to get it working by using a global controller.

    Global Controller:
    Code:
    Ext.define('MyApp.controller.StatusBarController', {    
        extend : 'Ext.app.Controller',
        alias: 'controller.StatusBarController',
    
        updateStatusBar : function(message) {
            var sb = Ext.getCmp('my-status');
        
            // Update the status bar later in code:        
            sb.setStatus({
                text : message,
                iconCls : 'ok-icon',
                clear : true
            // auto-clear after a set interval
            });
        }    
    });
    View Controller:

    Code:
     Ext.define('MyApp.controller.ResourcesPanelController', {    
        extend : 'Ext.app.ViewController',
        alias : 'controller.ResourcesController',
    
        onItemClick : function(tree, record, item, index, e, eOpts) {
            MyApp.app.getController('StatusBarController').updateStatusBar(
                    record.data.text + ' has been clicked');
        }
    });

  9. #9
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,451
    Answers
    3997

    Default

    I wouldn't use getController, fire an event in the ViewController and listen for it in the global controller. Using getController makes your logic too limiting. What if you refactor things and now you have to go hunting to fix the bindings you created. Look at my code, fire an event and listen using the listen config.
    Mitchell Simoens @LikelyMitch
    Modus Create, Senior Fullstack Engineer
    ________________
    Modus Create is based on the model of an open source team. We’re a remote, global team of experts in our field. To find out more about the work we do, head over to our website.

    Check out my GitHub:
    https://github.com/mitchellsimoens

  10. #10
    Sencha User
    Join Date
    Jun 2014
    Posts
    12

    Default

    Quote Originally Posted by mitchellsimoens View Post
    Code:
    Ext.define('MyApp.view.foo.BarController', {
        extend : 'Ext.app.ViewController',
        alias : 'controller.myapp-foo-bar',
    
        onSomething : function() {
            this.fireEvent('something', this, 'blah');
        }
    });
    Then any controller (view or global controller) can listen to it in the same way:

    Code:
    Ext.define('MyApp.controller.Baz', {
        extend : 'Ext.app.Controller',
    
        listen : {
            controller : {
                '*' : {
                    something : 'onSomething'
                }
            }
        },
    
        onSomething : function(controller, blah) {
        }
    });
    well it works just once in this situation:

    1. Baz listen all controller for event called 'something'.
    2. BarController fire 'something' event that catched by Baz so it call onSomething function.
    3. Destroy or close view (for the sake of name we call it 'BarView') that has BarController as its controller. For what reason may you ask? well, in Extjs 5 Guides Page on Application Architecture View Controllers they say about Lifecycle
      The ViewController, however, is created very early in the components lifecycle and is bound to that view for its entire lifetime. When that view is destroyed, the ViewController is likewise destroyed. This means that the ViewController is no longer forced to manage states where there is no view or many views.
    4. Show that BarView again.
    5. Make it so BarController fire 'something' event one more time.
    6. Baz ignore it, completely....... like a child crying out loud for a candy but her mother act like she didnt hear anything at all.......

Page 1 of 3 123 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •