2013-08-27 74 views
0

我正在處理具有多個模塊的應用程序。每個模塊由一個控制器,模塊/存儲和使用這些存儲的多個視圖組成。所以我決定創建主控制器和一個導航視圖。當用戶更改應用程序部分時,會加載相應的控制器。ExtJS從主控制器加載子控制器

這是我的主控制器的源代碼:

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

這是我的控制器的抽象的源代碼:

Ext.define('My.controller.ControllerX', { 
    extend: 'Ext.app.Controller', 
    stores: ['Store#1','Store#2'], 
    views: ['Widget#1','Widget#2','Widget#3'], 
    init: function() { 
     var container = My.getApplication().getContainerPanel(); 
     container.add(Ext.widget('Widget#1')); 
     container.add(Ext.widget('Widget#2')); 
     this.control({ ... }); 
     ... 
    } 
    ... 
}); 

一切正常,當我加載子控制器爲先時間。但是當我再次導航到同一個子控制器時,我遇到了商店的問題。商店就像他們被複制一樣。例如,當我在商店中添加新模型並同步商店時,它會添加兩個模型而不是一個,並將它們發送到服務器。

我在做什麼錯?

+0

我沒有發佈我的孩子控制器的內容,以避免不必要的信息超載你。加載並正常初始化時,它們工作得非常好。 – Stas

回答

0

好的,我解決了我的問題。我已經更新了我的主控制器,它在刪除視圖時不會銷燬視圖,而是將它們存儲在相應的變量中,並在導航到已經加載的部分時使用這些視圖。

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

此外,應用程序變得更快,因爲每次我們進入該部分時窗口部件(視圖)都不會重新構建。

0

Controller.init應該只能被調用一次。把log放在你動態加載的控制器init方法中,它很可能被多次調用。