在ExtJS 4 MVC中使用多个控制器
假设我有一个主控制器,那么我的应用程序的每个“模块”都有一个控制器。此主控制器包含视口,然后是标题(带有菜单)+一个“居中”容器,该容器在开始时为空 在菜单中单击将更改当前模块/控制器,并且临时视图(属于此控制器)将显示在居中容器中在ExtJS 4 MVC中使用多个控制器,extjs,controller,extjs4,extjs-mvc,Extjs,Controller,Extjs4,Extjs Mvc,假设我有一个主控制器,那么我的应用程序的每个“模块”都有一个控制器。此主控制器包含视口,然后是标题(带有菜单)+一个“居中”容器,该容器在开始时为空 在菜单中单击将更改当前模块/控制器,并且临时视图(属于此控制器)将显示在居中容器中 我认为这是一个非常简单的场景,但奇怪的是,我没有找到正确的方法。有什么想法吗?非常感谢 我就是这么做的:我在顶部有一个工具栏,一个左侧导航,中心位置是工作区(基本上是一个选项卡面板),就像你提到的那样。让我们了解应用程序的每一部分并进行解释。首先,这里是我的视口的外
我认为这是一个非常简单的场景,但奇怪的是,我没有找到正确的方法。有什么想法吗?非常感谢 我就是这么做的:我在顶部有一个工具栏,一个左侧导航,中心位置是工作区(基本上是一个选项卡面板),就像你提到的那样。让我们了解应用程序的每一部分并进行解释。首先,这里是我的视口的外观:
Ext.define('App.view.Viewport',{
extend: 'Ext.container.Viewport',
layout: 'border',
requires: [
'App.view.menu.NavigationPane',
'App.view.CenterPane',
'App.view.menu.Toolbar'
],
initComponent: function() {
Ext.apply(this, {
items: [{
region: 'north',
xtype: 'panel',
height: 24,
tbar: Ext.create('App.view.menu.Toolbar')
},{
title: 'Navigation Pane',
region: 'west',
width: 200,
layout: 'fit',
collapsible: true,
collapsed: true,
items: Ext.create('App.view.menu.NavigationPane')
},{
region: 'center',
xtype: 'centerpane'
}]
});
this.callParent(arguments);
}
});
您可以看到,我有一个工具栏(App.view.menu.toolbar),带有菜单和左侧导航(App.view.menu.NavigationPane)。这两个组件构成了我的主菜单或其他模块的网关。用户选择菜单项并将相应的模块视图(如表单、网格、图表等)加载到“中心窗格”中。中心窗格只是Ext.tab.Panel的派生类
正如您所说,我有一个主控制器,它处理来自工具栏和导航窗格的所有请求。它只处理工具栏和导航窗格的单击操作。这是我的AppController:
Ext.define('CRM.controller.AppController',{
extend: 'Ext.app.Controller',
init: function() {
this.control({
'apptoolbar button[action="actionA"]' : {
click : function(butt,evt) {
this.application.getController('Controller1').displayList();
}
},
.
. // Add all your toolbar actions & navigation pane's actions...
.
'apptoolbar button[action="actionB"]' : {
click : function(butt,evt) {
this.application.getController('Controller2').NewRequest();
}
}
});
}
});
Ext.define('CRM.controller.Controller2',{
extend: 'Ext.app.Controller',
refs: [
{ref:'cp',selector: 'centerpane'}, // reference to the center pane
// other references for the controller
],
views: ['c2.CreateForm','c2.EditForm','c2.SearchForm','c2.SearchForm'],
init: function() {
this.control({
'newform button[action="save"]' : {
// Do save action for new item
},
'editform button[action="save"]' : {
// update the record...
},
'c2gridx click' : {
// oh! an item was click in grid view
}
});
},
NewRequest: function() {
var view = Ext.widget('newform');
var cp = this.getCp(); // Get hold of the center pane...
cp.add(view);
cp.setActiveTab(view);
},
displayList: function() {
// Create grid view and display...
}
});
看看我的一个按钮处理器。我通过“应用程序”属性获得控制器:
this.application.getController('Controller2').NewRequest();
在getController方法的帮助下,我获取控制器的实例,然后调用控制器内的任何方法。现在让我们看一下模块控制器的框架:
Ext.define('CRM.controller.AppController',{
extend: 'Ext.app.Controller',
init: function() {
this.control({
'apptoolbar button[action="actionA"]' : {
click : function(butt,evt) {
this.application.getController('Controller1').displayList();
}
},
.
. // Add all your toolbar actions & navigation pane's actions...
.
'apptoolbar button[action="actionB"]' : {
click : function(butt,evt) {
this.application.getController('Controller2').NewRequest();
}
}
});
}
});
Ext.define('CRM.controller.Controller2',{
extend: 'Ext.app.Controller',
refs: [
{ref:'cp',selector: 'centerpane'}, // reference to the center pane
// other references for the controller
],
views: ['c2.CreateForm','c2.EditForm','c2.SearchForm','c2.SearchForm'],
init: function() {
this.control({
'newform button[action="save"]' : {
// Do save action for new item
},
'editform button[action="save"]' : {
// update the record...
},
'c2gridx click' : {
// oh! an item was click in grid view
}
});
},
NewRequest: function() {
var view = Ext.widget('newform');
var cp = this.getCp(); // Get hold of the center pane...
cp.add(view);
cp.setActiveTab(view);
},
displayList: function() {
// Create grid view and display...
}
});
我的模块的控制器只有与该模块相关的操作(模块的网格、表单等)。这将帮助您开始朝正确的方向滚动 在主控制器中,在菜单的单击事件处理程序中添加子控制器
Ext.define('MyAPP.controller.MainController',{
...
init:function()
{
this.control({
'menulink':
{
click:this.populateCenterPanel
}
});
},
populateCenterPanel:function()
{
this.getController('ChildController');
}
});
在启动函数中将侦听器添加到控制器添加事件中,如下所示-
Ext.application({
...
launch:function(){
this.controllers.addListener('add',this.newControllerAdded,this);
},
newControllerAdded:function(idx, ctrlr, token){
ctrlr.init();
}
});
现在,在ChildController的init方法中将动态嵌入视图的代码放入视口中
Ext.define('MyAPP.controller.ChildController',{
...
refs: [
{ref:'displayPanel',selector:'panel[itemId=EmbedHere]'}
]
init:function(){
var panel=this.getDisplayPanel();
panel.removeAll();
panel.add({
xtype:'mycustomview',
flex:1,
autoHeight:true,
...
});
}
});
HTH:)这也是我的想法,问题是我想避免孩子们知道什么是它的父母。这有点像婴儿在出生前选择父母,对吗p然后使用应用程序事件…让主控制器在单击菜单时触发应用程序事件,并让子控制器处理它。这就是我现在所做的,我将“主容器”的id传递给控制器,以便我可以正确使用“this.control”和“refs”。尽管如此,我仍然认为这是很多小技巧,我希望所有这些都能由框架进行动态管理:(感谢您的精彩解释,但对我来说仍然是一个问题。请查看我对之前答案的评论(techknowfreak)。对不起,我没听清楚。知道父控制器的所谓子控制器在哪里?您能详细说明一下吗?在上面的代码中没有从模块控制器到主控制器的交互。对吗?或者我理解您错了:)对不起,子控制器不知道父视图(“centerpane”在这里)。我希望模块(一堆控制器+视图)能够独立。