Javascript ExtJs最佳实践
似乎大多数ExtJS书籍和ExtJS简介只关注于展示所有优秀的功能,但大多数都没有真正解释如何使用ExtJS构建稳定、可维护的布局/应用程序。以及如何写它们而不造成无法阅读的混乱 我脑子里没有具体的应用程序,我只是想知道如何“美化”我的ExtJS代码。所以,如果你需要一个例子,一个“常规”的项目管理应用程序(库)或类似于工作板的东西最能描述我的想法 那么,当我想用ExtJS为客户端代码构建这些应用程序时,有人能分享一些关于如何构建这些应用程序的好链接或建议吗 提前感谢,, 干杯有用的链接:Javascript ExtJs最佳实践,javascript,extjs,Javascript,Extjs,似乎大多数ExtJS书籍和ExtJS简介只关注于展示所有优秀的功能,但大多数都没有真正解释如何使用ExtJS构建稳定、可维护的布局/应用程序。以及如何写它们而不造成无法阅读的混乱 我脑子里没有具体的应用程序,我只是想知道如何“美化”我的ExtJS代码。所以,如果你需要一个例子,一个“常规”的项目管理应用程序(库)或类似于工作板的东西最能描述我的想法 那么,当我想用ExtJS为客户端代码构建这些应用程序时,有人能分享一些关于如何构建这些应用程序的好链接或建议吗 提前感谢,, 干杯有用的链接: -
- -真的很有用
- -官方图坦卡蒙
- -由现实世界的ExtJS用户提供
- 作为一个组件,总是和爸爸说话-永远不要和你的兄弟姐妹说话(当然允许自己的孩子)
- 尽量避免冒泡
- 如果遵循#1,则不需要使用Ext.getCmp(),因为它太贵了,所以不要使用
- 考虑团队中其他人可重用的每个组件
- 在名称空间中使用适当的层次结构(并使用名称空间)
因为除了以下文档之外,只有几个主要规则……:) Sencha博客上关于十大最糟糕做法的文章值得一读 这篇博文的摘要 **请注意,所有的信用都归原博客文章的合法所有者所有 1。组件结构嵌套过多或不必要 有时开发人员使用冗余的嵌套组件,这可能会导致应用程序中出现意想不到的不吸引人的美学效果,比如双边框或意外的布局行为 坏的 好 在上面的示例中,嵌套面板是冗余的,因为网格是面板的扩展。 此外,表单、树、选项卡面板等其他元素都是面板的扩展 2。未能清理未使用的组件导致内存泄漏。 这是有史以来最重要的规则之一。在任何编程语言中,它都是非常重要的 重要的是确保不再使用的组件被正确丢弃,即使在 像Java这样的语言,GC为我们做所有的清理工作,我们应该确保我们没有 在我们处理完任何对象后,将其删除 坏的 每次用户在网格行上单击鼠标右键时,都会创建一个新的上下文菜单。看起来不错,因为我们 只看最新的菜单 坏(??) 这比最初的一个要好一些。每次用户访问时,它都使用相同的菜单对象 在栅格视图上单击鼠标右键。但是,即使我们关闭了网格视图,它也会使菜单保持活动状态 这不是我们需要的 好 在上面的视图中,当网格被破坏时,我们也会破坏菜单 3。怪物控制器 有些人编码像怪物。。。只是开玩笑,但是有一些大型控制器(不仅仅是控制器,还有其他组件:) 它由数千行代码组成,这些代码做的事情彼此之间根本没有关系 在开发开始时,找到一种将应用程序分解为不同处理单元的方法是非常重要的 项目,这样您就不会得到一个处理应用程序中所有进程的巨型控制器
var mySaveButton = myToolbar.items.getAt(2);
var myWindow = myToolbar.ownerCt;
建议:
用不同的方法分解你的应用程序
应用程序功能(在订单处理应用程序中-->订购、交付、客户查找…等)
视图(网格、表格等)
在ExtJS中,控制器可以相互通信
this.getController('SomeOtherController').runSomeFunction(myParm);
还可以触发任何控制器都可以侦听的应用程序级事件
MyApp.getApplication().fireEvent('myevent');
另外,另一个控制器侦听应用程序级事件
MyApp.getApplication().on({
myevent : doSomething
});
4。源代码的文件夹结构不好
在任何应用程序中,良好的结构都非常重要,因为它提高了项目的可读性和可维护性。
与其将所有控制器放在一个文件夹中,而将所有视图放在另一个文件夹中,不如对其进行逻辑结构
根据它们的功能
5。全局变量的使用
为什么使用全局变量不好?
有时它并不清楚它所持有的实际价值,因此它可能会导致很多困惑,比如
- 名称冲突
- 运行时很难发现难以调试的bug
我们能做些什么?
我们可以为它们定义一个单独的类并将它们存储在其中
5.1首先,我们创建一个单独的javascript文件,其中包含在使用应用程序时需要更改的变量
Runtime.js
5.2定义一个类来保存全局可用的数据,在本例中为“myLastCustomer”变量
5.3然后在整个应用程序中提供veriables
5.4当您想要获取或设置全局变量值时 5.4.1设定值Ext.application({ name : ‘MyApp’, requires : [‘MyApp.config.Runtime’], ... });
5.4.2获得价值MyApp.config.setMyLastCustomer(12345);
MyApp.config.getMyLastCustomer();
// 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'
}]
在上面的示例中,有两个具有相同名称的按钮,这会导致名称冲突。
要防止它,请使用“itemId”而不是id
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;
我们如何
MyApp.config.getMyLastCustomer();
// 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’);
var mySaveButton = myToolbar.items.getAt(2);
var myWindow = myToolbar.ownerCt;
var pictureSaveButton = Ext.ComponentQuery.query('#picturetoolbar > #savebutton')[0]; // Quering against the itemId
var mySaveButton = myToolbar.down(‘#savebutton’); // searching against itemId
var myWindow = myToolbar.up(‘window’);
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.
});
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
});
// 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.