我目前正在参加 Sencha Training 的 ExtJS 4 快速通道。我在 ExtJS(自 ExtJS 2.0 起)方面有很强的背景,并且非常想知道 MVC 是如何在 ExtJS 4 中实现的。
现在,以前,我模拟控制器的方式是将该责任委托给主容器。想象一下 ExtJS 3 中的以下示例:
Ext.ns('Test');
Test.MainPanel = Ext.extend(Ext.Container, {
initComponent : function() {
this.panel1 = new Test.Panel1({
listeners: {
firstButtonPressed: function(){
this.panel2.addSomething();
},
scope: this
}
});
this.panel2 = new Test.Panel2();
this.items = [this.panel1,this.panel2];
Test.MainPanel.superclass.initComponent.call(this);
}
});
Test.Panel1 = Ext.extend(Ext.Panel, {
initComponent : function() {
this.addEvents('firstButtonPressed');
this.tbar = new Ext.Toolbar({
items: [{
text: 'First Button',
handler: function(){
this.fireEvent('firstButtonPressed');
}
}]
});
Text.Panel1.superclass.initComponent.call(this);
}
});
Test.Panel2 = Ext.extend(Ext.Panel, {
initComponent : function() {
this.items = [new Ext.form.Label('test Label')]
Test.Panel2.superclass.initComponent.call(this);
},
addSomething: function(){
alert('add something reached')
}
});
如您所见,我的 MainPanel (除了持有两个面板的事实之外)还委托事件并因此在两个组件之间创建通信,因此模拟了某种控制器。
在 ExtJS 4 中直接实现了 MVC。真正让我印象深刻的是控制器实际获取组件的方式是通过 QuerySelector ,在我看来这很容易出错。让我们来看看:
Ext.define('MyApp.controller.Earmarks', {
extend:'Ext.app.Controller',
views:['earmark.Chart'],
init:function () {
this.control({
'earmarkchart > toolbar > button':{
click:this.onChartSelect
},
'earmarkchart tool[type=gear]':{
click:this.selectChart
}
});
}
});
因此,正如我们在此处看到的,Controller 了解专用图表按钮和工具的方式是通过选择器。现在让我们想象一下,我正在更改我的专用图表中的布局,并且我实际上将按钮移到了工具栏之外。突然间我的应用程序坏了,因为我总是需要注意更改布局可能会对与之关联的控制器产生影响。
有人可能会说我可以使用 itemId 来代替,但我需要再次注意,如果我删除了一个组件,我需要分散查找我的控制器中是否有针对该 itemId 的隐藏引用,以及我不能每个父组件具有相同的 itemId,因此如果我在 Panel1 中有一个名为“testId”的 itemId,并且在 Grid1 中有相同的 itemId,那么我仍然需要选择是需要来自 Panel1 还是来自 Grid1 的 itemId。
我知道 Query 非常强大,因为它为您提供了很大的灵活性,但在我看来,这种灵活性的代价非常高,如果我有一个由 5 人组成的团队开发用户界面,我需要解释这个概念,我由于我之前提到的几点,他们会犯很多错误。
您对此有何总体看法?以某种方式与事件进行交流会更容易吗?这意味着如果我的控制器实际上知道他期望事件的视图,那么可以只触发一个事件 dosomethingController 并且关联的控制器会得到它,而不是所有这些查询问题。