Sencha Touch 2.1通过参考控制器获取视图

时间:2013-04-16 20:46:18

标签: controller ref sencha-touch-2.1

尝试以编程方式将视图推送到视口的主导航视图时,出现以下错误:

Uncaught TypeError:当调用MainController.js文件中的以下行时,Object [object Object]没有方法'getMainPanel':

var mainnav = this.getMainPanel();

我只是试图通过xtype获取导航视图的参考,以便我可以执行mainnav.push('viewName'),具体取决于是否有数据调用返回的数据。数据和数据调用工作正常,我可以手动将所需的视图添加到主视图端口,使导航视图毫无价值,这不是我的意图。

我尝试通过xtype,'MainPanel'添加“Ref”,并通过分配和id,id:'MainPanel'并在控制器中尝试:

refs: {
      mainPanel: 'MainPanel'
}

和Id:

refs:{           mainPanel:'#MainPanel'     }

无论如何,错误都是一样的。

作为参考,我试图遵循以下资源中描述的情况:

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

这是我的代码:

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

更新Main.js并更新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'});
                }
            }
        });
    }
});

2 个答案:

答案 0 :(得分:2)

您想为itemId视图分配Main个配置。所以:

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',
        ...
    }
});

然后在您的控制器中,您可以通过Main引用ref视图。所以:

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

});

现在你应该可以var mainnav = this.getMainPanel();

您推送新视图的方式也是错误的。您应该在推送String时传递Object。查看docs

所以在你的情况下你可能想要这样做:

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

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

假设CharListNewCharacter是相应观点的xtypes

修改 好的,如果您仍然遇到同样的问题,可能是因为您在init函数中执行此操作。尝试将逻辑移至launch函数。事实证明,在应用程序启动之前调用init函数。 http://docs.sencha.com/touch/2.1.1/#!/api/Ext.app.Controller-cfg-init

答案 1 :(得分:0)

实际上,当您在函数init()中调用mainnav = this.getMainPanel();时,尚未创建MainPanel视图,这就是您未定义的原因,尝试使用单击处理程序执行此操作,您将看到它将起作用,因为所有视图将在点击时刻创建。

尝试这样的事情:

Ext.define('IT.controller.UserController', {
    extend: 'Ext.app.Controller',
    views: [
        'user.authentication'
    ],
    refs: [
        {
            ref: 'Authentication',
            selector: 'Authentication',
        }
    ],
    init: function() {
        console.log('Initialized Users');
        var me = this;
        me.control(
            {
                '#login-user-btn': {
                    click: me.handleLoginUser
                }
            }
            );
        },
    handleLoginUser: function(button, e) {
        alert('Ok');
        //var form= button.up('form').getForm();
        var form = this.getAuthentication();
        alert(form);
    }
})