Heim  >  Artikel  >  Web-Frontend  >  Ext JS 4官方文档之三 -- 类体系概述与实践_基础知识

Ext JS 4官方文档之三 -- 类体系概述与实践_基础知识

WBOY
WBOYOriginal
2016-05-16 17:46:251094Durchsuche

Ext JS 4从底层对类体系进行了重构,这是Ext JS历史上的第一次对类体系的巨大重构。新的架构几乎被应用到每一个Ext JS 4的类中,所以希望您在开始编码前能对它有一定的了解,这是非常重要的。
这篇手册适用于任何想创建新类或者继承Ext JS 4中现存类的开发人员,分为4部分:
第一部分: "概述" -- 解释了创建一个强健的类体系的必要性
第二部分: "命名规范" -- 讨论了对类、方法、属性、变量和文件的最佳命名规范
第三部分: "实践" -- 提供了详细的一步一步的代码示例
第四部分: "错误处理和调试" -- 提供了非常有用的关于如何处理异常的秘诀和技巧

一. 概述
Ext JS 4拥有超过300个类,迄今为止,我们已经有一个超过200,000开发者的庞大社区,他们来自世界各地的各种编程背景。对于如此大规模的一个框架,我们面临着一个巨大的挑战来提供一个通用的代码体系结构:
友好并易于学习
开发迅速,容易调试,部署简单
组织良好,可扩展和可维护
JavaScript是一个无类型的,面向原型的语言,这种语言最强大的特性之一就是灵活性。它可以通过各种不同的方法,使用各种不同的编码风格和技巧来完成同一个工作。然而,这种特性却带来了一个不可预见的代价,如果没有一个统一的结构,JavaScript代码就很难理解、维护和重用。
基于类的编程,换句话说,使用最流行的OOP模型。基于类的语言通常是强类型语言,提供了封装,并有标准的编码约定。一般情况下,让开发者遵循一组统一的编码规则,写的代码才更可能是可预测的,可扩展的和可延伸的。然而,它们却没有了像JavaScript这类语言一样的动态能力。
每种方法都有它们自己的优缺点,但是我们能否同时利用它们两者的优点部分,而隐藏它们的缺点部分呢?答案是肯定的,我们已经在Ext JS 4中实现了这个解决方案。

二. 命名规范
在你的代码中始终使用一致的基于类、命名空间和文件名的命名规范,这将有助于保持你的代码易组织、结构化和易读。
1) 类
类名可以只包含字母数字字符,数字在大多数情况下是不允许的,除非它们属于一个技术术语。不要使用下划线,连字符,或任何其他非字母数字字符。例如:
MyCompany.useful_util.Debug_Toolbar 是不可以的
MyCompany.util.Base64 是可以的
类名应该通过使用对象的点表达式(.)属性,从而放置到适当的命名空间中。至少,类名应该有一个唯一的顶层命名空间。例如:
MyCompany.data.CoolProxy
MyCompany.Application
顶层命名空间和类名都应该采用驼峰命名法,除此之外,其他的应该全部小写。例如:
MyCompany.form.action.AutoLoad
不是由Sencha的Ext JS发布的类不能使用Ext作为顶层命名空间。
缩略词也应该遵循上述的驼峰命名规范。例如:
Ext.data.JsonProxy 代替了 Ext.data.JSONProxy
MyCompany.util.HtmlParser 代替了 MyCompary.parser.HTMLParser
MyCompany.server.Http 代替了 MyCompany.server.HTTP
2) 源文件
类的名称直接映射到存储它们的文件路径中,因此,每一个文件只能有一个类,例如:
Ext.util.Observable 存储在 /to/src/Ext/util/Observable.js
Ext.form.action.Submit 存储在 /to/src/Ext/form/action/Submit.js
MyCompany.chart.axis.Numeric 存储在 /to/src/MyCompany/chart/axis/Numeric.js
路径/to/src是您的应用程序的类的根目录,所有类都应该放置在这个共同的根目录下。
3) 方法和变量
与类名类似,方法和变量名可以只包含字母数字字符,数字在大多数情况下是不允许的,除非它们属于一个技术术语。不要使用下划线,连字符,或任何其他非字母数字字符。
方法和变量名也应该总是驼峰式的,这也适用于缩略词。
示例:
可接受的方法名称: encodeUsingMd5(),getHtml()代替了getHTML(),getJsonResponse()代替了 getJSONResponse(), parseXmlContent()代替了parseXMLContent()
可接受的变量名称: var isGoodName, var base64Encoder, var xmlReader, var httpServer
4) 属性
类属性名完全遵循与上述的方法和变量相同的命名规范,除了静态常量。
静态类属性即常量应该全部大写,例如:
Ext.MessageBox.YES = "Yes"
Ext.MessageBox.NO = "No"
MyCompany.alien.Math.PI = "4.13"

三. 实践
1. 声明
1.1) 老的方法
如果您曾经使用过任何先前版本的Ext JS,您肯定很熟悉使用Ext.extend来创建类:
var MyWindow = Ext.extend(Object, { ... });
这种方法很容易创建一个继承自其他类的新类,然而除了直接继承,我们没有一个很好的API来创建类的其他方面,如配置,静态配置和混入类,我们稍后将详细回顾它们。
让我们看看另外一个例子:
My.cool.Window = Ext.extend(Ext.Window, { ... });
在这个示例中,我们希望创建一个新的具有命名空间的类,并让它继承Ext.Window,这里有两个问题需要解决:
My.cool 必须是已存在的命名空间对象,这样我们才能分配Window作为其属性
Ext.Window 必须存在且被加载,这样才能引用它
第一点通常用Ext.namespace(别名是Ext.ns)来解决,这个方法递归地创建不存在的对象,而让人厌烦的是你必须总是记得把它们添加到 Ext.extend 之前:
Ext.ns('My.cool');My.cool.Window = Ext.extend(Ext.Window, { ... });
然而第二个问题就不太容易解决了,因为 Ext.Window可能依赖于很多其他的类,它可能是直接地或间接地继承自那些依赖类,而这些依赖类可能又依赖于其他类。由于这个原因,在Ext JS 4之前编写的应用程序通常都会引入整个库文件 ext-all.js,尽管可能仅仅只需要其中的很小一部分。
1.2) 新的方法
Ext JS 4消除了所有这些缺点,您只需要记得唯一的一个创建类的方法是:Ext.define,它的基本语法如下:
Ext.define(className, members, onClassCreated);
className: 类名
members 是一个大对象,代表了一个类成员的集合,是一系列的键-值对
onClassCreated 是一个可选的回调函数,当类的所有依赖项都准备好了,并且类被完全创建时,就会被调用。这个回调函数在很多情况下是很有用的,我们将在第四部分中深入讨论。
示例:

复制代码 代码如下:

Ext.define('My.sample.Person',{
name: 'Unknown',
constructor: function(name) {      
if (name) {        
this.name = name;      
}},
eat: function(foodType) {
alert(this.name + " is eating: " + foodType);  }});
var aaron = Ext.create('My.sample.Person', 'Aaron');
aaron.eat("Salad"); // alert("Aaron is eating: Salad");

注意,我们是用 Ext.create()方法创建了一个My.sample.Person的实例。当然我们也可以使用new 关键字(new My.sample.Person()),然而我们建议您养成总是使用 Ext.create 的习惯,因为它可以利用动态加载功能。更多关于动态加载的信息,请看Ext JS 4入门指南。

2. 配置
在Ext JS 4中,我们引入了一个专用的config属性,它会在类创建前,由强大的预处理器类 Ext.Class 进行处理,具有如下特性:
配置是从其他类成员完全封装的
每个config属性的getter和setter方法会在类原型中自动的生成,如果类里没有定义这些方法的话
同时,也会为每个config属性生成一个apply方法,自动生成的setter方法会在内部设置值之前调用这个apply方法。如果你想要在设置值之前运行自定义逻辑,就可以覆盖这个apply方法。如果apply没有返回值,setter方法将不会设置值。让我们看看下面的applyTitle方法:
下面的例子定义了一个新类:
复制代码 代码如下:

Ext.define('My.own.Window', {  /** @readonly */
isWindow: true,
config: {
title: 'Title Here',
bottomBar: {
enabled: true,
height: 50,
resizable: false     }   },
constructor: function(config) {    
this.initConfig(config);   },
applyTitle: function(title) {    
if (!Ext.isString(title) || title.length === 0) {
alert('Error: Title must be a valid non-empty string');    
} else {      
return title;    
}   },
applyBottomBar: function(bottomBar) {    
if (bottomBar && bottomBar.enabled) {      
if (!this.bottomBar) {        
return Ext.create('My.own.WindowBottomBar', bottomBar);      
} else {        
this.bottomBar.setConfig(bottomBar);      
}    
}  
}});

下面是如何使用这个新类的例子:
复制代码 代码如下:

var myWindow = Ext.create('My.own.Window', {
title: 'Hello World',
bottomBar: {
height: 60  }});
alert(myWindow.getTitle()); // alerts "Hello World"
myWindow.setTitle('Something New');
alert(myWindow.getTitle()); // alerts "Something New"
myWindow.setTitle(null); // alerts "Error: Title must be a valid non-empty string"
myWindow.setBottomBar({ height: 100 }); // Bottom bar's height is changed to 100


3. 静态配置
静态配置成员可以使用statics属性来定义:
复制代码 代码如下:

Ext.define('Computer', {
statics: {
instanceCount: 0,
factory: function(brand) {      
// 'this' in static methods refer to the class itself      
return new this({brand: brand});     }   },
config: {
brand: null},
constructor: function(config) {    
this.initConfig(config);     
// the 'self' property of an instance refers to its class    
this.self.instanceCount ++;   }});
var dellComputer = Computer.factory('Dell');var appleComputer = Computer.factory('Mac');
alert(appleComputer.getBrand());
// using the auto-generated getter to get the value of a config property. Alerts "Mac"
alert(Computer.instanceCount);
// Alerts "2"


四. 错误处理和调试
Ext JS 4包含了一些有用的特性,可以帮助你调试和错误处理:
你可以使用Ext.getDisplayName()方法来获取任何方法的显示名称,这是特别有用的,当抛出错误时,可以用来在错误描述里显示类名和方法名:
throw new Error('[' + Ext.getDisplayName(arguments.callee) + '] Some message here');
当错误从由Ext.define()定义的类的任何方法中抛出时,如果你使用的基于WebKit的浏览器(Chrome或者Safari)的话,你会在调用堆栈中看到方法名和类名。例如,下面是从Chrome中看到的堆栈信息:
Ext JS 4官方文档之三 -- 类体系概述与实践_基础知识
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn