Model view controller ExtJS从主控制器加载子控制器

Model view controller ExtJS从主控制器加载子控制器,model-view-controller,extjs,extjs4,Model View Controller,Extjs,Extjs4,我正在开发有几个模块的应用程序。每个模块由一个控制器、模块/存储和使用这些存储的多个视图组成。所以我决定创建主控制器和一个导航视图。当用户更改应用程序的部分时,将加载相应的控制器 这是我的主控制器的源代码: Ext.define('My.controller.Navigation', { extend: 'Ext.app.Controller', views: ['layout.Navbar'], _loadedControllers: [], init: function() { va

我正在开发有几个模块的应用程序。每个模块由一个控制器、模块/存储和使用这些存储的多个视图组成。所以我决定创建主控制器和一个导航视图。当用户更改应用程序的部分时,将加载相应的控制器

这是我的主控制器的源代码:

Ext.define('My.controller.Navigation', {
extend: 'Ext.app.Controller',
views: ['layout.Navbar'],
_loadedControllers: [],
init: function() {
    var me = this;
    me.control({
        'navbar > tabpanel': {
            tabchange: me.handleNavChange
        }
    });
},
handleNavChange: function(tabPanel, newCard, oldCard, eOpts) {
    var app = My.getApplication(),
        container = app.getContainerPanel(),
        components = Ext.ComponentQuery.query('viewport > panel > panel:not([cls~=bpte-layout])'),
        name = this.formatControllerName(newCard.itemId),
        i=0;
    //Remove initialized widgets:
    for(; i < components.length; i++) {
        container.remove( components[i], true );
    }
    //Load and initialize controller:
    controller = app.getController(name);
    if(this.isControllerLoaded(name))
        controller.init();
    this.addLoadedController(name);
},
formatControllerName: function(id) {
    return id.charAt(0).toUpperCase() + id.substr(1).toLowerCase();
},
isControllerLoaded: function(name) {
    for(var i=0; i < this._loadedControllers.length; i++) {
        if(this._loadedControllers[i] == name)
            return true;
    }
    return false;
},
addLoadedController: function(name) {
    this._loadedControllers.push(name);
}});
当我第一次加载子控制器时,一切正常。但是当我再次导航到同一个子控制器时,我遇到了存储的问题。商店的行为就像它们是复制品一样。例如,当我在应用商店中添加新模型,然后同步应用商店时,它会添加两个模型,而不是一个,并将它们都发送到服务器


我做错了什么?

Controller.init
应该只调用一次。在动态加载的控制器
init
方法中放置一个
log
,它可能会被多次调用。

好的,我为自己解决了问题。我更新了主控制器,使其在删除视图时不会破坏视图,它将视图存储在相应的变量中,并在导航到已加载的部分时使用这些视图

Ext.define('My.controller.Navigation', {
extend: 'Ext.app.Controller',
views: ['layout.Navbar'],
_loadedControllers: {},
init: function() {
    var me = this;
    me.control({
        'navbar > tabpanel': {
            tabchange: me.handleNavChange
        }
    });
},
handleNavChange: function(tabPanel, newCard, oldCard, eOpts) {
    var app = My.getApplication(),
        container = app.getContainerPanel(),
        components = Ext.ComponentQuery.query('viewport > panel > panel:not([cls~=bpte-layout])'),
        currentController = this.formatControllerName(oldCard.itemId),
        newController = this.formatControllerName(newCard.itemId),
        i=0;
    //Store old components and remove them from container:
    this._loadedControllers[currentController] = components;
    for(; i < components.length; i++) {
        container.remove( components[i], false );
    }
    if(this.isControllerLoaded(newController)) {
        //Restore widgets of already loaded controller:
        for(i=0; i < this._loadedControllers[newController].length; i++) {
            container.add(this._loadedControllers[newController][i]);
        }
    } else {
        //Load new controller:
        app.getController(newController);
    }
},
formatControllerName: function(id) {
    return id.charAt(0).toUpperCase() + id.substr(1).toLowerCase();
},
isControllerLoaded: function(name) {
    for(var key in this._loadedControllers) {
        if(!this._loadedControllers.hasOwnProperty(key))
            continue;
        if(key == name)
            return true;
    }
    return false;
}});
Ext.define('My.controller.Navigation'{
扩展:“Ext.app.Controller”,
视图:['layout.Navbar'],
_LoadedController:{},
init:function(){
var me=这个;
自我控制({
“导航栏>选项卡面板”:{
tabchange:me.handleNavChange
}
});
},
handleNavChange:功能(选项卡面板、新卡、旧卡、eOpts){
var app=My.getApplication(),
container=app.getContainerPanel(),
components=Ext.ComponentQuery.query('视口>面板>面板:非([cls~=bpte布局]),
currentController=this.formatControllerName(oldCard.itemId),
newController=this.formatControllerName(newCard.itemId),
i=0;
//存储旧组件并将其从容器中移除:
这。_loadedControllers[currentController]=组件;
对于(;i

此外,应用程序变得更快,因为每次进入该部分时,小部件(视图)都不会重新生成。

我没有发布我的子控制器的内容,以免给您带来不必要的信息。它们在正常加载和初始化时工作得非常好。
Ext.define('My.controller.Navigation', {
extend: 'Ext.app.Controller',
views: ['layout.Navbar'],
_loadedControllers: {},
init: function() {
    var me = this;
    me.control({
        'navbar > tabpanel': {
            tabchange: me.handleNavChange
        }
    });
},
handleNavChange: function(tabPanel, newCard, oldCard, eOpts) {
    var app = My.getApplication(),
        container = app.getContainerPanel(),
        components = Ext.ComponentQuery.query('viewport > panel > panel:not([cls~=bpte-layout])'),
        currentController = this.formatControllerName(oldCard.itemId),
        newController = this.formatControllerName(newCard.itemId),
        i=0;
    //Store old components and remove them from container:
    this._loadedControllers[currentController] = components;
    for(; i < components.length; i++) {
        container.remove( components[i], false );
    }
    if(this.isControllerLoaded(newController)) {
        //Restore widgets of already loaded controller:
        for(i=0; i < this._loadedControllers[newController].length; i++) {
            container.add(this._loadedControllers[newController][i]);
        }
    } else {
        //Load new controller:
        app.getController(newController);
    }
},
formatControllerName: function(id) {
    return id.charAt(0).toUpperCase() + id.substr(1).toLowerCase();
},
isControllerLoaded: function(name) {
    for(var key in this._loadedControllers) {
        if(!this._loadedControllers.hasOwnProperty(key))
            continue;
        if(key == name)
            return true;
    }
    return false;
}});