Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 25

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

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

    Default

    That is a bug that has been reported and opened: http://www.sencha.com/forum/showthread.php?290043
    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

  2. #12
    Sencha Premium Member Zdeno's Avatar
    Join Date
    Nov 2009
    Location
    Prague
    Posts
    769
    Answers
    38

    Default

    Quote Originally Posted by mitchellsimoens View Post
    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) {
        }
    });
    Hi Mitch, are there any limitations? I use container/toolbar with button on 4 tabs. When I simply put console log to listener, I see the event was fired 4 times even I clicked on active tab button only. Debug by console.log(this.getView().id) returns different IDs so Im absolutely sure the event is fired on each tab and not in clicked button handler only. It almost looks like a bug.

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

    Default

    I'm not sure what you're doing so it's hard to say what's going on.
    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

  4. #14
    Sencha Premium Member Zdeno's Avatar
    Join Date
    Nov 2009
    Location
    Prague
    Posts
    769
    Answers
    38

    Default

    Ah ok. Lets have following code:

    1) Simple menu button with controller and handler

    Code:
    Ext.define('MyApp.view.Button', {
        extend: 'Ext.button.Button',
    
        alias: 'widget.myapp-button',    
        
        requires: [
            'MyApp.view.ButtonController'
        ],
    
        controller: 'button'
    
        text: 'Menu button',
    
        menu: {
            items: [
                {
                    text: 'Upload file',
                    handler: 'onFileUploadClick'
                }
            ]
        }
    });
    2) Button controller

    Code:
    Ext.define('MyApp.view.ButtonController', {
        extend: 'Ext.app.ViewController',
    
        alias: 'controller.button',
    
        onFileUploadClick: function() {
            console.log('-- onFileUploadClick --');
            this.fireEvent('fileuploadclick', this);
        }
    });
    3) Panel somewhere in application

    Code:
    Ext.define('MyApp.view.PanelController', {
        extend: 'Ext.app.ViewController',
    
        alias: 'controller.panel',
    
        listen: {
            controller: {
                '*' : {
                    fileuploadclick: 'onFileUploadClick'
                }
            }
        },
    
        onFileUploadClick: function(controller) {
            console.log(controller);
            console.log(this.getView().id);
            console.log('fileuploadclick event listener');
        }
    });
    When I put button 4 times to application and do click on some of them I get following output:

    Code:
    -- onFileUploadClick --
    contructor { ... _id: "controller-176" ... }
    ext-comp-1079
    fileuploadclick event listener
    contructor { ... _id: "controller-176" ... }
    ext-comp-1115
    fileuploadclick event listener
    contructor { ... _id: "controller-176" ... }
    ext-comp-1151
    fileuploadclick event listener
    contructor { ... _id: "controller-176" ... }
    ext-comp-1187
    fileuploadclick event listener
    I think correct output should be ViewID where the button was clicked.

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

    Default

    Trying to have a runnable test in this I created this fiddle:



    I used your 2 ViewControllers and Button class and I created a simple Panel class that holds 4 instances of your button. When I run this, I expand any of the button menus and click on the menu item and it logs out:

    -- onFileUploadClick --
    constructor {compDomain: constructor, type: "button", eventbus: constructor, hasListeners: statics.prepareClass.HasListeners, events: Object}
    myapp-panel-1010
    fileuploadclick event listener
    Great. Do the same thing only to a different button and I get:

    -- onFileUploadClick --
    constructor {compDomain: constructor, type: "button", eventbus: constructor, hasListeners: statics.prepareClass.HasListeners, events: Object}
    myapp-panel-1010
    fileuploadclick event listener
    The controller instances being logged are the different MyApp.view.ButtonController instances, the _id properties are different for me. So for my experience with the fiddle I created, everything is working as I expect it to.
    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

  6. #16
    Sencha User
    Join Date
    Oct 2014
    Posts
    20
    Answers
    2

    Default

    try to think easy. There are different ways to do this. If u want some static links maybe set it in the constructor. If you want to profit from the visitor pattern than you can use custom events. You can also just search for this instance and execute this method.

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

    Default

    Quote Originally Posted by akrillo View Post
    try to think easy. There are different ways to do this. If u want some static links maybe set it in the constructor. If you want to profit from the visitor pattern than you can use custom events. You can also just search for this instance and execute this method.
    Also try to think outside of right now. Right now may be ok for a controller to call another controller's method directly (although I'd argue against that) but as you develop your application will evolve and have refactors and new features and whatever. Any of this may break any of those static linkages and you'd have to hunt them all down and have regression tests to cover all of that. Firing an event and listening to it is much safer and more flexible.
    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. #18
    Sencha Premium Member Zdeno's Avatar
    Join Date
    Nov 2009
    Location
    Prague
    Posts
    769
    Answers
    38

    Default

    Quote Originally Posted by mitchellsimoens View Post
    Also try to think outside of right now. Right now may be ok for a controller to call another controller's method directly (although I'd argue against that) but as you develop your application will evolve and have refactors and new features and whatever. Any of this may break any of those static linkages and you'd have to hunt them all down and have regression tests to cover all of that. Firing an event and listening to it is much safer and more flexible.
    I can only agree with Mitchell. Flexibility is plus in big apps.

    To Mitch: Ill take a look at my code and let you know. Not sure what Im doing wrong. I always get multiple calls.

  9. #19
    Sencha Premium Member Zdeno's Avatar
    Join Date
    Nov 2009
    Location
    Prague
    Posts
    769
    Answers
    38

    Default


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

    Default

    The reason why that's happening is because you have 3 instances of the MyApp.view.Panel created and therefore 3 instances of the MyApp.view.PanelController created. Each PanelController instance is going to listen for the fileuploadclick event so when it fires, each PanelController instance will execute their own onFileUploadClick method.

    I updated some of the console.logs in the onFileUploadClick to show what the controller's ID is that is firing the event, what the current controller's ID is and what the panel's ID is. You will notice that the firing controller ID logs are all the same but the current controller IDs are different.
    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

Page 2 of 3 FirstFirst 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
  •