如何解决ExtJS 4-重用MVC架构中的组件
| 我有一个用户列表,如果单击此列表中的一个项目,则会打开一个窗口。每个用户都使用同一窗口,并且可以同时打开多个窗口。该窗口显示用户信息,因此对于这些组件,我具有相同的商店和相同的型号。 但是,如果我在特定窗口中加载数据,则在所有其他打开的窗口中加载相同的数据。Ext.define(\'Cc.view.absence.Grid\',{
extend: \'Ext.grid.Panel\',alias: \'widget.absencegrid\',border:false,initComponent: function() {
Ext.apply(this,{
store: Ext.create(\'Ext.data.Store\',{
model: \'Cc.model.Absence\',autoLoad: false,proxy: {
type: \'ajax\',reader: {
type: \'json\'
}
}
}),columns: [
{header: \'Du\',dataIndex: \'startdate\',flex: 3,renderer: this.formatDate},{header: \'Au\',dataIndex: \'enddate\',{header: \'Exercice\',dataIndex: \'year\',align: \'center\',flex: 1},{header: \'Statut\',xtype:\'templatecolumn\',tpl:\'<img src=\"../images/status-{statusid}.png\" alt=\"{status}\" title=\"{status}\" />\',{header: \'Type d\\\'absence\',dataIndex: \'absencetype\',flex: 2},{header: \'Commentaires\',dataIndex: \'comment\',flex: 6}
],dockedItems: [{
xtype: \'toolbar\',dock: \'top\',items: [
{ xtype: \'tbfill\'},{ xtype: \'button\',text: \'Rafraichir\',action: \'refresh\',iconCls: \'item-rafraichir\' }
]
}]
});
this.callParent(arguments);
},formatDate: function(date) {
if (!date) {
return \'\';
}
return Ext.Date.format(date,\'l d F Y - H:i\');
}
});
我的控制器:
Ext.define(\'Cc.controller.Absences\',{
extend: \'Ext.app.Controller\',models: [\'Absence\',\'AbsenceHistory\'],views: [],refs: [
{ ref: \'navigation\',selector: \'navigation\' },{ ref: \'tabPanel\',selector: \'tabpanel\' },{ ref: \'absencePanel\',selector: \'absencepanel\' },{ ref: \'refreshButton\',selector: \'absencepanel button[action=refresh]\'},{ ref: \'absenceGrid\',selector: \'absencegrid\' },{ ref: \'absenceHistory\',selector: \'absencehistory\' },],init: function() {
this.control({
\'absencepanel button[action=refresh]\': {
click: this.onClickRefreshButton
},\'absencegrid\': {
selectionchange: this.viewHistory
},\'absencegrid > tableview\': {
refresh: this.selectAbsence
},});
},selectAbsence: function(view) {
var first = this.getAbsenceGrid().getStore().getAt(0);
if (first) {
view.getSelectionModel().select(first);
}
},viewHistory: function(grid,absences) {
var absence = absences[0],store = this.getAbsenceHistory().getGrid().getStore();
if(absence.get(\'id\')){
store.getProxy().url = \'/absence/\' + absence.get(\'id\') +\'/history\';
store.load();
}
},onClickRefreshButton: function(view,record,item,index,e){
var store = this.getAbsenceGrid().getStore();
store.load();
},});
其他控制器,仅创建一个不存在的实例。Panel:
Ext.define(\'Cc.controller.Tools\',stores: [\'Tools\',\'User\' ],models: [\'Tool\'],{ ref: \'toolList\',selector: \'toollist\' },{ ref: \'toolData\',selector: \'toollist dataview\' }
],init: function() {
this.control({
\'toollist dataview\': {
itemclick: this.loadTab
},onLaunch: function() {
var dataview = this.getToolData(),store = this.getToolsStore();
dataview.bindStore(store);
},loadTab: function(view,e){
var tabPanel = this.getTabPanel();
switch (record.get(\'tab\')) {
case \'absences\':
if(Ext.getCmp(\'absence-panel\')){
tabPanel.setActiveTab(Ext.getCmp(\'absence-panel\'));
}
else {
var panel = Ext.create(\'Cc.view.absence.Panel\',{
id: \'absence-panel\'
}),store = panel.getGrid().getStore();
panel.enable();
tabPanel.add(panel);
tabPanel.setActiveTab(panel);
store.getProxy().url = \'/person/\' + this.getUserId() +\'/absences\';
store.load();
}
break;
default:
break;
}
},getUserId: function(){
var userStore = this.getUserStore();
var id = userStore.first().get(\'id\')
return id;
}
});
另一个控制器,它创建许多不存在的实例。
Ext.define(\'Cc.controller.Agents\',stores: [\'Agents\'],models: [\'Agent\',\'Absence\',views: [\'agent.List\',\'agent.Window\',\'absence.Panel\',\'absence.Grid\',\'absence.History\'],refs: [
{ ref: \'agentList\',selector: \'agentlist\' },{ ref: \'agentData\',selector: \'agentlist dataview\' },{ ref: \'agentWindow\',selector: \'agentwindow\' },init: function() {
this.control({
\'agentlist dataview\':{
itemclick: this.loadWindow
},onLaunch: function() {
var dataview = this.getAgentData(),store = this.getAgentsStore();
dataview.bindStore(store);
},loadWindow: function(view,e){
if(!Ext.getCmp(\'agent-window\'+record.get(\'id\'))){
var window = Ext.create(\'Cc.view.agent.Window\',{
title: \'À propos de \'+record.get(\'firstname\')+\' \'+record.get(\'lastname\'),id: \'agent-window\'+record.get(\'id\')
}),tabPanel = window.getTabPanel();
absencePanel = window.getAbsencePanel();
store = absencePanel.getGrid().getStore();
absencePanel.enable();
tabPanel.add(absencePanel);
tabPanel.setActiveTab(absencePanel);
store.getProxy().url = \'/person/\' + record.get(\'id\') +\'/absences\';
store.load();
}
Ext.getCmp(\'agent-window\'+record.get(\'id\')).show();
}
});
和missing.Panel视图,missing.Grid的容器:
Ext.define(\'Cc.view.absence.Panel\',{
extend: \'Ext.panel.Panel\',alias: \'widget.absencepanel\',title: \'Mes absences\',iconCls: \'item-outils\',closable: true,border: false,disabled: true,layout: \'border\',initComponent: function() {
this.grid = Ext.create(\'Cc.view.absence.Grid\',{
region: \'center\'
});
this.history = Ext.create(\'Cc.view.absence.History\',{
region: \'south\',height: \'25%\'
});
Ext.apply(this,{
items: [
this.grid,this.history
]
});
this.callParent(arguments);
},getGrid: function(){
return this.grid;
},getHistory: function(){
return this.history;
}
});
解决方法
是。这是我正在做什么的更多详细说明。希望您已经阅读了完整的论坛。仍然有一个我们不清楚的信息。那就是在控制器中使用\“ stores \”属性的确切用法。恕我直言,Sencha团队应使用复杂的示例对MVC进行更详细的说明。
是的,您新发布的内容是正确的。创建新视图后,请创建商店的新实例!现在,从论坛讨论中,人们开始争论MVC。我一定会和斯蒂芬克一起去。我在这里所做的就是将新的store实例注入我的视图。而且我忽略了控制器的5属性。
这是一个例子:
这是我的看法。我在选项卡面板上显示的面板(包含用户个人资料信息):
Ext.define(\'Dir.view.profile.View\',{
extend: \'Ext.panel.Panel\',alias : \'widget.profileview\',title : \'Profile\',profileId: 1,// default and dummy value
initComponent: function() {
// configure necessary stuff,I access my store etc here..
// console.log(this.profileStore);
this.callParent(arguments);
},// Other view methods goes here
});
现在,看一下我的控制器:
Ext.define(\'Dir.controller.Profile\',{
extend: \'Ext.app.Controller\',//stores: [\'Profile\'],--> Note that I am NOT using this!
refs: [
{ref:\'cp\',selector: \'centerpane\'}
],views: [\'profile.View\'],init: function() {
// Do your init tasks if required
},displayProfile: function(selectedId) {
// create a new store.. pass your config,proxy url etc..
var store = Ext.create(\'Dir.store.Profile\',{profileId: selectedId});
console.log(\'Display Profile for ID \' + selectedId);
// Create instance of my view and pass the new store
var view = Ext.widget(\'profileview\',{profileId: selectedId,profileStore: store});
// Add my new view to centeral panel and display it...
this.getCp().add(view);
this.getCp().setActiveTab(view);
}
});
我的displayProfile()
是从某些事件侦听器(菜单,树等)中调用的,并传递一个ID。我的控制器使用此ID来设置新的商店和视图。我希望上面的代码能使您清楚地了解我昨天所说的内容。
在您的控制器中,您将必须添加“ 9”,以便ExtJS知道您拥有这样的商店。这是因为我们没有使用stores
属性。
现在,您可以在其他地方重用这些创建的商店,可以将它们添加到StoreManager。这样,您可以在任何地方访问创建的商店,添加和删除商店。但这会带来管理存储实例的开销。
为什么要共享具有不同视图的商店的同一实例?当您有新视图时,请创建商店的新实例。这样一来,刷新后的其他窗口将不会显示更新的数据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。