1. #1
    Sencha User
    Join Date
    Jan 2009
    Location
    West Coast
    Posts
    37
    Vote Rating
    0
    slchorne is on a distinguished road

      0  

    Default MVC and Button events

    MVC and Button events


    I'm trying to wrap my head around MVC, but I can't seem to get a simple button handler event to work. I've defined a simple panel with a single button. But when i click/tap on the button, the event doesn't fire.

    What am I missing ? I've defined the panel here

    Code:
    Ext.application({
        name: 'myApp',
    
        // register any relevant controllers, ([ ] why).
        // these are relative to the app's 'name' so the full
        // name when you extend Ext.app.Controller should be 
        //    'myApp.controller.myC'
        controllers: [ 'myC' ],
    
        // the 'launch' handler is called when ALL the .js files have loaded
        launch: function() {
    
            console.log( 'launch' , myApp );
    
            // create the main panel
            var p = Ext.create('Ext.Panel',{
                title: 'test',
                layout: 'hbox',
                items: [
                    {
                        xtype: 'button',
                        itemId: 'mybutton',
                        text: "click me",
                    }
                ]
            });
            // Add and render the main panel
            Ext.Viewport.add( p );
        }
    
    });
    Then define the handler here

    Code:
    Ext.define('myApp.controller.myC', {
        extend: 'Ext.app.Controller',
    
        init: function() {
    
            console.log( 'init control' , myApp );
    
            // try and find something
            var A = Ext.ComponentQuery.query('#mybutton');
            console.log ( "q: " , A );
    
    
            this.control({
                '#mybutton':{
                    itemtap: this.clickHandler
                },
            });
        },
        clickHandler: function(){
            console.log('it was clicked');
        }
    });
    Also, can someone explain why i need the 'controllers' config to register the controller. This seems messy if i rename the controller. Is there a way to 'auto register' controllers.

  2. #2
    Sencha Premium Member
    Join Date
    Oct 2011
    Location
    Paris, France
    Posts
    187
    Vote Rating
    3
    olouvignes is on a distinguished road

      0  

  3. #3
    Sencha User
    Join Date
    Jan 2009
    Location
    West Coast
    Posts
    37
    Vote Rating
    0
    slchorne is on a distinguished road

      0  

    Default


    I'm not sure what you mean. 'refs' are just shortcuts to let you get to the object via a different namespace. But they only are useful when you are in the actual even handler. And '#mybutton' should give me a ref directly to that button anyway. ( I know this because 'Ext.ComponentQuery.query('#mybutton'); " returns the button I want to listen to).

    So I could do this

    Code:
    refs: [         { 
            ref: 'buttons',             
            selector: '#mybutton'         
    }     ],
    And then get to that component via getButtons()

    But the problem here is that 'clickHandler' is not even being called. 'this.control' is not being parsed correctly.

  4. #4
    Sencha User
    Join Date
    Nov 2007
    Posts
    29
    Vote Rating
    0
    joseph09 is on a distinguished road

      0  

    Default


    Try changing itemtap to tap in this.control



    Code:
    Ext.define('myApp.controller.myC', {
        extend: 'Ext.app.Controller',
    
        init: function() {
    
            console.log( 'init control' , myApp );
    
            // try and find something
            var A = Ext.ComponentQuery.query('#mybutton');
            console.log ( "q: " , A );
    
    
            this.control({
                '#mybutton':{
                    tap: this.clickHandler
                },
            });
        },
        clickHandler: function(){
            console.log('it was clicked');
        }
    });

  5. #5
    Sencha User
    Join Date
    Jan 2009
    Location
    West Coast
    Posts
    37
    Vote Rating
    0
    slchorne is on a distinguished road

      0  

    Default


    I tried both 'tap' and 'itemtap' (the jury is still out on which one is correct, if you read the threads) and neither of them work.

    If I add a listener directly to the button, it does work, but this is an exercise in getting to understand the MVC model

    Code:
                            xtype: 'button',
                            itemId: 'mybutton',
                            ui: 'decline',
                            text: "click me",
                            listeners: {
                                tap: function() {
                                    console.log ( 'clicked tap' ) ;
                                }
                            }

  6. #6
    Sencha User
    Join Date
    Sep 2011
    Posts
    125
    Vote Rating
    0
    oddz is on a distinguished road

      0  

    Default


    I believe this is related to this bug.

    Unless buttons are added in the initialization phase events do not seem to occur.

  7. #7
    Sencha User
    Join Date
    Jan 2009
    Location
    West Coast
    Posts
    37
    Vote Rating
    0
    slchorne is on a distinguished road

      0  

    Default


    That would also explain this bug:

    http://www.sencha.com/forum/showthre...973#post662973

  8. #8
    Sencha User
    Join Date
    Nov 2007
    Posts
    29
    Vote Rating
    0
    joseph09 is on a distinguished road

      0  

    Default


    Try putting the button inside of a view and using a ref to it

  9. #9
    Sencha User
    Join Date
    Jan 2009
    Location
    West Coast
    Posts
    37
    Vote Rating
    0
    slchorne is on a distinguished road

      0  

    Default


    I'm not sure what you mean (this is where my MVC education grinds to a halt).
    Can you provide an example ?

  10. #10
    Sencha User
    Join Date
    Nov 2007
    Posts
    29
    Vote Rating
    0
    joseph09 is on a distinguished road

      0  

    Default


    No problem, I am just learning as well -

    Instead of placing the button in the launch handler of app.js place it in a view

    app.js
    Code:
    Ext.Loader.setConfig({ enabled: true });
    Ext.application({
        name: 'MyApp',
        controllers: ['myC']
    });

    app/controller/Main.js
    Code:
    Ext.define('myApp.controller.myC', {
        extend: 'Ext.app.Controller',
    
        config: {
            profile: Ext.os.deviceType.toLowerCase()
        },
    
        views : [
            'Main'
        ],
    
        stores: ['myStore'],
    
        refs: [{
                ref: 'main',
                selector: 'mainview',
                autoCreate: true,
                xtype: 'mainview'
            }, {
                ref: 'myButton',
                selector: '#myButton'
            }, {
                ref: 'myList',
                selector: 'mylist'
            }
        ],
    
        init: function() {
            this.getMainView().create();
            this.control({
                '#myButton': {
                    tap: this.onButtonTap
                }
            });
        },
        
        onButtonTap: function() {
            //mainView = this.getMain();
            //myList = this.getMyList();
            //mainView.setActiveItem(myList);
            console.log('Button Clicked!');
        },
    });


    app/view/Main.js
    Code:
        Ext.define('myApp.view.Main', {
            extend: 'Ext.Panel',
            id: 'mainView',
            requires: [
                'Ext.Toolbar',
                'Ext.Button'
            ],
            config: {
                fullscreen: true,
    
                layout: {
                    type: 'card',
                    animation: {
                        type: 'slide',
                        direction: 'left',
                        duration: 250
                    }
                },
    
                items: [{
                    xtype: 'toolbar',
                    id: 'topToolbar',
                    docked: 'top',
                    items: [{
                        xtype: 'button',
    		    text: 'My Button',
    	     	    iconCls: 'home', 
    		    iconMask: true,
    		    labelCls: 'button_label', 
                	    id: 'myButton'
            	}]
                }]
            }
        });

    The above code is rough and probably has errors but is meant to illustrate the point of placing the button in the view.

    A couple of recommendations would be to use camelCaps (for example myButton instead of mybutton)
    and to use id: 'myButton' instead of itemId: 'myButton'