Sencha博客中关于最糟糕的十个做法值得一读。
以下是该博客文章的概要,请注意所有权归原博客作者所有。
1. 过度或不必要的组件结构嵌套
有时开发人员使用冗余的嵌套组件,可能会导致应用程序出现意外的不吸引人的美学效果,例如双重边框或意外的布局行为。
错误示例
items: [{
xtype : 'panel',
title: ‘My Cool Grid’,
layout: ‘fit’,
items : [{
xtype : 'grid',
store : 'MyStore',
columns : [{...}]
}]
}]
好的
layout: ‘fit’,
items: [{
xtype : 'grid',
title: ‘My Cool Grid’,
store : 'MyStore',
columns : [{...}]
}]
Ext.define('MyApp.view.MyGrid',{
extend : 'Ext.grid.Panel',
columns : [{...}],
store: ‘MyStore’,
initComponent : function(){
this.callParent(arguments);
this.on({
scope : this,
itemcontextmenu : this.onItemContextMenu
});
},
onItemContextMenu : function(view,rec,item,index,event){
event.stopEvent();
Ext.create('Ext.menu.Menu',{
items : [{
text : 'Do Something'
}]
}).showAt(event.getXY());
}
});
Ext.define('MyApp.view.MyGrid',{
extend : 'Ext.grid.Panel',
store : 'MyStore',
columns : [{...}],
initComponent : function(){
this.menu = this.buildMenu();
this.callParent(arguments);
this.on({
scope : this,
itemcontextmenu : this.onItemContextMenu
});
},
buildMenu : function(){
return Ext.create('Ext.menu.Menu',{
items : [{
text : 'Do Something'
}]
});
},
onItemContextMenu : function(view,rec,item,index,event){
event.stopEvent();
this.menu.showAt(event.getXY());
}
});
这个版本比最初的更好。当用户右键单击网格视图时,它每次都使用相同的菜单对象。但即使我们关闭了网格视图,它仍会保持菜单处于打开状态,这不是我们需要的。
好的做法:
Ext.define('MyApp.view.MyGrid',{
extend : 'Ext.grid.Panel',
store : 'MyStore',
columns : [{...}],
initComponent : function(){
this.menu = this.buildMenu();
this.callParent(arguments);
this.on({
scope : this,
itemcontextmenu : this.onItemContextMenu
});
},
buildMenu : function(){
return Ext.create('Ext.menu.Menu',{
items : [{
text : 'Do Something'
}]
});
},
onDestroy : function(){
this.menu.destroy();
this.callParent(arguments);
},
onItemContextMenu : function(view,rec,item,index,event){
event.stopEvent();
this.menu.showAt(event.getXY());
}
});
this.getController('SomeOtherController').runSomeFunction(myParm);
也可以触发一个应用程序级别的事件,任何控制器都可以监听。
MyApp.getApplication().fireEvent('myevent');
MyApp.getApplication().on({
myevent : doSomething
});
4. 源代码的文件夹结构不佳
在任何应用程序中,良好的结构都非常重要,因为它提高了项目的可读性和可维护性。
与其将所有控制器放在一个文件夹中,将所有视图放在另一个文件夹中,不如根据它们的功能进行逻辑上的结构化。
5. 使用全局变量
为什么使用全局变量是不好的?
有时候它所持有的实际值并不清楚,因此可能会导致很多混淆,例如:
我们该怎么做呢?
我们可以为它们定义一个单独的类并将它们存储在其中。
5.1 首先创建一个单独的javascript文件,其中包含需要在使用应用程序时更改的变量。
Runtime.js
5.2 定义一个类来保存全局可用的数据,在这种情况下是“myLastCustomer”变量。
Ext.define(‘MyApp.config.Runtime’,{
singleton : true,
config : {
myLastCustomer : 0 // initialize to 0
},
constructor : function(config){
this.initConfig(config);
}
});
5.3 然后在整个应用程序中使变量可用。
Ext.application({
name : ‘MyApp’,
requires : [‘MyApp.config.Runtime’],
...
});
5.4 每当您想要获取或设置全局变量值时
5.4.1 设置值
MyApp.config.setMyLastCustomer(12345);
5.4.2 获取数值
MyApp.config.getMyLastCustomer();
6. 在组件中使用id是不好的想法吗?
为什么?
6.1 因为你定义的每个id都应该是唯一的。在大型应用程序中,这可能会导致很多混淆和问题。
6.2 让框架处理组件的命名是很容易的。
// here we define the first save button
xtype : 'toolbar',
items : [{
text : ‘Save Picture’,
id : 'savebutton'
}]
// somewhere else in the code we have another component with an id of ‘savebutton’
xtype : 'toolbar',
items : [{
text : ‘Save Order’,
id : 'savebutton'
}]
xtype : 'toolbar',
itemId : ‘picturetoolbar’,
items : [{
text : 'Save Picture',
itemId : 'savebutton'
}]
// somewhere else in the code we have another component with an itemId of ‘savebutton’
xtype : 'toolbar',
itemId: ‘ordertoolbar’,
items : [{
text : ‘Save Order’,
itemId: ‘savebutton’
}]
var pictureSaveButton = Ext.ComponentQuery.query('#picturetoolbar > #savebutton')[0];
var orderSaveButton = Ext.ComponentQuery.query('#ordertoolbar > #savebutton')[0];
// assuming we have a reference to the “picturetoolbar” as picToolbar
picToolbar.down(‘#savebutton’);
7. 组件引用不可靠
使用组件定位来获取组件的引用并不是一个好主意。因为有人可能会更改组件的位置,而不知道它在应用程序的其他部分中被引用。
var mySaveButton = myToolbar.items.getAt(2);
var myWindow = myToolbar.ownerCt;
我们如何获取参考?
使用“ComponentQuery”或“up”/“down”方法。
var pictureSaveButton = Ext.ComponentQuery.query('#picturetoolbar > #savebutton')[0]; //
针对itemId进行查询
var mySaveButton = myToolbar.down(‘#savebutton’); // searching against itemId
var myWindow = myToolbar.up(‘window’);
8. 未能遵循大小写命名规范
使用良好的命名规范是最佳实践,因为它可以提高代码的一致性并使其易于阅读和理解。
此外,对于您定义的所有类、变量和方法,使用有意义的名称也非常重要。
错误示例:
Ext.define(‘MyApp.view.customerlist’,{ // should be capitalized and then camelCase
extend : ‘Ext.grid.Panel’,
alias : ‘widget.Customerlist’, // should be lowercase
MyCustomConfig : ‘xyz’, // should be camelCase
initComponent : function(){
Ext.apply(this,{
store : ‘Customers’,
….
});
this.callParent(arguments);
}
});
好的
Ext.define(‘MyApp.view.CustomerList’,{ // Use of capitalized and then camelCase
extend : ‘Ext.grid.Panel’,
alias : ‘widget.customerlist’, // use of lowerCase
myCustomConfig : ‘xyz’, // Use of camelCase
initComponent : function(){
Ext.apply(this,{
store : ‘Customers’,
….
});
this.callParent(arguments);
}
});
Ext.define('MyApp.view.MyGrid',{
extend : 'Ext.grid.Panel',
initComponent : function(){
Ext.apply(this,{
store : ‘MyStore’,
region : 'center',
......
});
this.callParent(arguments);
}
});
Ext.define('MyApp.view.MyGrid',{
extend : 'Ext.grid.Panel',
initComponent : function(){
Ext.apply(this,{
store : ‘MyStore’,
......
});
}
});
Ext.create('MyApp.view.MyGrid',{
region : 'center' // specify the region when the component is created.
});
有另一种定义带默认值组件的方法(在这种情况下,“region”属性),并在需要更改默认值时覆盖默认值。
好处:
Ext.define('MyApp.view.MyGrid',{
extend : 'Ext.grid.Panel',
region : 'center', // default region
initComponent : function(){
Ext.apply(this,{
store : ‘MyStore’,
......
});
}
});
Ext.create(‘MyApp.view.MyGrid’,{
region : ‘north’, // overridden region
height : 400
});
10. 让你的代码比必要复杂
有许多方法可以使简单的代码变得复杂。
其中一种方式是通过逐个访问表单中的每个字段来加载表单数据。
不好的例子:
// suppose the following fields exist within a form
items : [{
fieldLabel : ‘User’,
itemId : ‘username’
},{
fieldLabel : ‘Email’,
itemId : ‘email’
},{
fieldLabel : ‘Home Address’,
itemId : ‘address’
}];
// you could load the values from a record into each form field individually
myForm.down(‘#username’).setValue(record.get(‘UserName’));
myForm.down(‘#email’).setValue(record.get(‘Email’));
myForm.down(‘#address’).setValue(record.get(‘Address’));
好的
items : [{
fieldLabel : ‘User’,
name : ‘UserName’
},{
fieldLabel : ‘Email’,
name : ‘Email’
},{
fieldLabel : ‘Home Address’,
name : ‘Address’
}];
myForm.loadRecord(record); // use of "loadRecord" to load the entire form at once.