Sencha Touch 2.1 Get View by Ref in Controller

SouthPlatte picture SouthPlatte · Apr 16, 2013 · Viewed 9.7k times · Source

When trying to programatically push a view into the main navigation view on the viewport, I get the following error:

Uncaught TypeError: Object [object Object] has no method 'getMainPanel' when the following line in the MainController.js file is called:

var mainnav = this.getMainPanel();

I am simply trying to get a ref to the navigation view by xtype so that I can perform a mainnav.push('viewName') depending on if there is data returned from a data call. The data and data call are working fine, and I can manually add the desired views to the main view port, rendering the navigation view worthless, which is not my intention.

I have tried adding the "Ref" by xtype, 'MainPanel' and also by assigning and id, id: 'MainPanel' and in the controller trying:

refs: {
      mainPanel: 'MainPanel'
}

and by Id:

refs: { mainPanel: '#MainPanel' }

No matter, the error is the same.

For reference I have attempted to follow the situations described in the following resources:

http://docs.sencha.com/touch/2.1.1/#!/guide/controllers

http://docs.sencha.com/touch/2.0.2/#!/api/Ext.ComponentQuery

http://www.sencha.com/forum/showthread.php?179143-View-reference-getter-undefined

Sencha Touch 2- Unable to get ref view from controller

Sencha Touch 2.0 Controller refs attribute not working?

Sencha Touch 2.0 and navigation.View - MVC

Here is my code:

app.js

Ext.application({
name: 'AddCharSheet',
views: ['Main'],
models: ['CharacterSelectModel'],
stores: ['CharacterSelectStore'],
controllers: ['MainController'],

launch: function(){
    Ext.Viewport.add({
        xtype: 'MainPanel'
    });
}
});

Main.js

   Ext.define('AddCharSheet.view.Main', {
    extend: 'Ext.navigation.View',
    requires: ['AddCharSheet.view.CharacterSelect', 'AddCharSheet.view.AddNewCharacter', 'Ext.Toolbar', 'Ext.Panel'],
    xtype: 'MainPanel',
    config: {

    }
    });

MainController.js

Ext.define('AddCharSheet.controller.MainController',{
Extend: 'Ext.app.Controller',

config: {
    stores: ['AddCharSheet.store.CharacterSelectStore'],
    models: ['AddCharSheet.model.CharacterSelectModel'],
    views: ['AddCharSheet.view.AddNewCharacter', 'AddCharSheet.view.CharacterSelect'],

    refs: {
        mainPanel: 'MainPanel'
    },
    control: {

    },
    launch: function() {
    }
},

init: function(){
    var chs = Ext.getStore('charSelStore');
    var mainnav = this.getMainPanel();
    chs.load({
        callback: function(recs, operation){
            if(this.getCount() > 0){
                mainnav.push('CharList');
            }
            else{
                mainnav.push('NewCharacter');
            }
        }
    });
}
});

Update Main.js and update MainController.js

Main.js

Ext.define('AddCharSheet.view.Main', {
    extend: 'Ext.navigation.View',
    requires: ['AddCharSheet.view.CharacterSelect', 'AddCharSheet.view.AddNewCharacter', 'Ext.Toolbar', 'Ext.Panel'],
    xtype: 'MainPanel',
    config: {
        itemId: 'mainpanel'
    }
});

MainController.js

Ext.define('AddCharSheet.controller.MainController',{
    Extend: 'Ext.app.Controller',

    config: {
        stores: ['AddCharSheet.store.CharacterSelectStore'],
        models: ['AddCharSheet.model.CharacterSelectModel'],
        views: ['AddCharSheet.view.AddNewCharacter', 'AddCharSheet.view.CharacterSelect'],

        refs: {
            mainPanel: {
                autoCreate: true,
                selector: '#mainpanel',
                xtype: 'MainPanel'
            }
        },
        control: {

        },
        launch: function() {
        }
    },

    init: function(){
        var chs = Ext.getStore('charSelStore');
        var mainnav = this.getMainPanel();
        chs.load({
            callback: function(recs, operation){
                if(this.getCount() > 0){
                    mainnav.push({xtype: 'CharList'});
                }
                else{
                    mainnav.push({ xtype: 'NewCharacter'});
                }
            }
        });
    }
});

Answer

cclerv picture cclerv · Apr 16, 2013

You want to assign an itemIdconfig to your Main view. So:

Ext.define('AddCharSheet.view.Main', {
    extend: 'Ext.navigation.View',
    requires: ['AddCharSheet.view.CharacterSelect', 'AddCharSheet.view.AddNewCharacter',        'Ext.Toolbar', 'Ext.Panel'],
    xtype: 'MainPanel',
    config: {
        ...,
        itemId: 'mainpanel',
        ...
    }
});

Then in your controller you reference your Main view via ref. So:

Ext.define('AddCharSheet.controller.MainController',{
    Extend: 'Ext.app.Controller',

    config: {
        stores: ['AddCharSheet.store.CharacterSelectStore'],
        models: ['AddCharSheet.model.CharacterSelectModel'],
        views: ['AddCharSheet.view.AddNewCharacter', 'AddCharSheet.view.CharacterSelect'],

        refs: {
            mainPanel : {
                autoCreate: true,
                selector: '#mainpanel',
                xtype: 'MainPanel'
            },
        },
        control: {

        },
        launch: function() {

        }
},

init: function(){
    var chs = Ext.getStore('charSelStore');
    var mainnav = this.getMainPanel();
    chs.load({
        callback: function(recs, operation){
            if(this.getCount() > 0){
                mainnav.push('CharList');
            }
            else{
                mainnav.push('NewCharacter');
            }
        }
    });
}

});

Now you should be able to do var mainnav = this.getMainPanel();

Also the way you are pushing the new views is wrong. You are passing a String when you should be pushing an Object. Check the docs.

So in your case you may want to do this:

mainnav.push({  
    xtype:'CharList'
});

and

mainnav.push({  
    xtype:'NewCharacter'
});

assuming CharList and NewCharacterare the xtypes of the respective views.

Edit: Ok if you are still having the same issue, it could be because you are doing this in the init function. Try moving your logic to the launch function instead. It turns out the init function gets called before the application launches. http://docs.sencha.com/touch/2.1.1/#!/api/Ext.app.Controller-cfg-init