鸣谢:http://www.cnblogs.com/youring2/archive/2013/08/22/3274135.html

--------------------------------------------------------------------------

本篇博客主要介绍了Etxjs如何自定义类的,以及Extjs的继承、属性的封装,这类似于java语言的继承、封装的特点。此外,在java语言中,分层是重要的思想,如类的定义与创建其实例并调用方法一般都是分别写在不同的java文件中,javascript语言由于没有类的概念,因此总是所有的代码写在一个js文件中,而Extjs则不同,它与java语言一样具有面向对象的特性,在本博客中所介绍的Extjs的动态加载描述了Extjs是如何将类的定义与创建类的实例及调用方法进行分层的。

一、什么是define?

define是Extjs的一个方法,用于定义一个类或覆盖。详情见API:http://extjs-doc-cn.github.io/ext4api/#!/api/Ext

二、ExtJS 中自定义类

在ExtJS中,定义一个Person类:

Ext.onReady(function(){
Ext.define('Person',{
name:'wang',
say:function(){
alert('hi,'+this.name);
} })
var obj = new Person();
obj.say();
})

在这段代码中,我们使用了Ext.define方法自定义一个Person类,它具有Name,具有Say 方法,运行结果如下:

在上面的类中,name属性被赋了一个指定的值,显然,除了静态属性,在类中的属性仅需被声明,在创建实例时进行赋值,这就需要构造函数了。看下面的代码:

Ext.onReady(function(){
Ext.define("Person2", {
//定义、初始化成员属性
Name: '',
Age: 0,
//定义成员方法
Say: function (msg) {
Ext.Msg.alert(this.Name + " Says:", msg);
},
//定义构造函数
constructor: function (name, age) {
this.Name = name;
this.Age = age;
} });
var Tom = new Person2("Tom", 26);
Tom.Say("Hello");
})

运行结果:

三、ExtJS 中类的继承

ExtJS 允许对现有的类进行扩展,其扩展可以通过继承来实现。接下来我们就对刚刚使用ExtJS定义的Person2类进行继承,定义一个Developer类,它继承自Person2,同时还拥有Coding方法,代码如下:

/**
* 此js演示了Etxjs类的继承
*/
Ext.onReady(function(){ //基类
Ext.define("Developer", {
extend: 'Person2',//继承
Coding: function (code) {
Ext.Msg.alert(this.Name + " 正在编码..", code);
},
constructor: function(){
this.callParent(arguments);
}
}); var Bill = new Developer("Bill", 26);
Bill.Coding("int num1 = 0; ");
})

从代码中可看出,ExtJS 使用 extend来实现继承。我们为Developer 类添加了Coding 方法,这是我们对Person类进行的扩展。在构造函数中,通过调用this.callParent 方法,实现对属性的初始化。需要说明的是,如果此处只调用了父类的构造方法,则可以省略掉,ExtJS 会自动为我们调用父类的构造函数。所以我们此处的代码可以进行简化:

/**
* 此js演示了Etxjs类的继承
*/
Ext.onReady(function(){ //基类
Ext.define("Developer", {
extend: 'Person2',//继承
Coding: function (code) {
Ext.Msg.alert(this.Name + " 正在编码..", code);
}
}); //基类在new实例时如果在其类中没有定义构造方法,则调用其父类的构造方法。
var Bill = new Developer("Bill", 26);
Bill.Coding("int num1 = 0; ");
})

需要注意的是:1.如果你在子类中使用了构造函数,ExtJS 则不会再自动调用父类的构造函数;2.像java导包一样,在html中要导入父类的js文件,代码如下:

<!-- 导入父类 -->
<script type="text/javascript" src="../js/define/define2.js"></script>
<script type="text/javascript" src="../js/define/define3.js"></script>

运行结果:

四、ExtJS 中类的选项 - config

首先看一个例子,我们在ExtJS中定义一个Window对象,代码如下:

var win = Ext.create("Ext.window.Window", {
title: '示例窗口,
width: 300,
height: 200
});
win.show();

在上面的代码中,我们通过Ext.create方法创建了一个Window 对象,Ext.create 方法的第一个参数是类名,第二个参数是类的选项,它是一个JSON格式的对象,用来初始化Window对象。我们的窗口运行如下:

试想一下,如果我们的类中有几十个属性,那么我们使用构造函数就要传入几十个参数来对它完成初始化,这是一件很恐怖的事情。还好ExtJS 为我们提供了这种便利,我们可以在定义类的时候为它添加配置项——config,它是Extjs的属性包装器,为属性提供get和set方法。

我们来修改Person类,使它可以通过config初始化:

/**
* define-config
* 此js演示了在定义的类中将类的成员属性放在config中并且如何实例化对象的。
*/
Ext.onReady(function(){
Ext.define("Person", {
config: {
Name: '',
Age: 0
},
Say: function (msg) {
Ext.Msg.alert(this.Name + " Says:", msg);
},
Say2: function (msg) {//在方法中,“this.config.属性名”和“this.属性名”的形式都可以调用成员属性。
Ext.Msg.alert(this.config.Name+","+this.Age + " Says:", msg);
},
constructor: function (config) {
this.initConfig(config);
}
}); //注意:因为在Person类中将成员属性放进了config中,因此已不能用new的方式进行实例化了。
var Jack = new Person('Jack',28);
// Jack.Say('hi');
// alert(Jack.getAge()); //使用Ext的create方法创建并返回一个实例
var Tom = Ext.create("Person", {
Name: 'Tom',
Age: 26
});
Tom.Say("Hello");
// alert(Tom.getAge());//26 注:“Tom.config.Age”、“Tom.Age”都可以得到Age的值 //使用Ext自动生成的set、get方法设置、访问实例属性
Tom.setAge(18);//注:“Tom.Age=18”也可以——这是js赋值的方法
// alert(Tom.getAge());//18 注:“Tom.Age”也可以——这是js取值的方法
})

我们在类的定义中添加了config项,将需要在配置中完成的属性添加在里面,而在构造函数中,我们通过调用this.initConfig方法完成对config的初始化;在定义Person类对象的时候,使用Ext.create方法,传入类名Person以及配置项,运行结果:

五、ExtJS 中类的别名 - alias

在我们查看ExtJS API 的时候,在左侧常会有这样的说明:

红色方框圈出的部分是这个类的别名,它对应类的全称是 Ext.window.Window,由此可以看出别名更加简单,容易记忆和书写。我们在实例化类的时候,可以使用别名来替代类名全称,例如我们之前定义的win对象,他的代码可以修改为:

/**
* define-alias
* 此js演示了利用"alias"给定义的类起别名。
*/
Ext.onReady(function(){
Ext.define("vo.Person", {
config: {
Name: '',
Age: 0
},
alias:"Person",//给定义的类起个别名
Say: function (msg) {
Ext.Msg.alert(this.Name + " Says:", msg);
},
Say2: function (msg) {//在方法中,“this.config.属性名”和“this.属性名”的形式都可以调用成员属性。
Ext.Msg.alert(this.config.Name+","+this.Age + " Says:", msg);
},
constructor: function (config) {
this.initConfig(config);
}
}); //使用Ext的create方法创建并返回一个实例
var Tom = Ext.create("Person", {
Name: 'Tom',
Age: 26
});
Tom.Say("Hello"); })

六、ExtJS 中的动态加载

在Ext.create 方法的介绍中,有这样一段描述:

它的意思是:如果Ext.loader 可用,且类还没有被定义,它将试图通过同步加载来加载类。

接下来我们来试试类动态加载的功能。我们的类vo.Person 类的位置是:

下面是Person.js的代码:

/**
* define
* 此js定义一个Person类
*/ Ext.define("vo.Person", {
config: {
Name: '',
Age: 0
},
alias:"Person",//给定义的类起个别名
Say: function (msg) {
Ext.Msg.alert(this.Name + " Says:", msg);
},
Say2: function (msg) {//在方法中,“this.config.属性名”和“this.属性名”的形式都可以调用成员属性。
Ext.Msg.alert(this.config.Name+","+this.Age + " Says:", msg);
},
constructor: function (config) {
this.initConfig(config);
}
});

下面是在HTML中需要引用的js(define6.js)代码:

/**
* define-alias
* 此js演示了Ext的动态加载
*/
//js获取项目根路径,如:http://localhost:8081/extjsTest1
function getRootPath(){
//获取当前网址,如: http://localhost:8081/extjsTest1/define/define6.jsp
var curWwwPath=window.document.location.href;
//获取主机地址之后的目录,如: extjsTest1/define/define6.jsp
var pathName=window.document.location.pathname;
var pos=curWwwPath.indexOf(pathName);
//获取主机地址,如: http://localhost:8081
var localhostPaht=curWwwPath.substring(0,pos);
//获取带"/"的项目名,如:/extjsTest1
var projectName=pathName.substring(0,pathName.substr(1).indexOf('/')+1);
return(localhostPaht+projectName);
} Ext.onReady(function(){ Ext.Loader.setConfig({
enabled:true,
paths:{
vo: getRootPath()+"/js/vo"//告诉Extjs命名空间“vo”的路径
}
}) /**
* 在Extjs创建vo.Person的实例Tom时发现该类没有被定义,因此它会加载命名空间vo指定路径下的Person.js,
* 这就是Extjs的动态加载。
*/
var Tom = Ext.create("vo.Person", {//注意:使用动态加载,应使用类的全名,如果使用别名Extjs无法找到正确的路径。
Name: 'Tom',
Age: 26
});
Tom.Say("Hello"); })

在完成Loader 的配置以后,我们就可以移除掉对Person.js的引用了,下面是HTML引用文件:

<link rel="stylesheet"  type="text/css" href="../ext-4.2.1/resources/ext-theme-neptune/ext-theme-neptune-all.css"> 

<script type="text/javascript" src="../ext-4.2.1/ext-all.js"></script>
<script type="text/javascript" src="../ext-4.2.1/locale/ext-lang-zh_CN.js"></script> <script type="text/javascript" src="../js/define/define6.js"></script>

可以看到,上面并没有引用项目中的"../js/Vo/Person.js"这个js文件,运行结果:

另外,我们还可以手动的加载Person.js,代码如下:

/**
* define-alias
* 此js演示了Ext的动态加载
*/ //js获取项目根路径
function getRootPath(){
var curWwwPath=window.document.location.href;
var pathName=window.document.location.pathname;
var pos=curWwwPath.indexOf(pathName);
var localhostPaht=curWwwPath.substring(0,pos);
var projectName=pathName.substring(0,pathName.substr(1).indexOf('/')+1);
return(localhostPaht+projectName);
} Ext.onReady(function(){ Ext.Loader.setConfig({
enabled:true,
paths:{
vo: getRootPath()+"/js/vo"//告诉Extjs命名空间“vo”的路径
}
}) //加载Person.js
Ext.require("vo.Person"); var Tom = Ext.create("Person", {//fail:使用Ext.require方法加载Person.js无法用vo.Person的别名Person创建实例
Name: 'Tom',
Age: 26
});
Tom.Say("Hello"); })

但可惜的是,目前得到的是失败的结果,运行,在谷歌浏览器出现以下错误:

说明Ext.require没有正确加载Person.js

小结:Extjs的动态加载不仅实现了分层设计的思想,而且对于提高系统性能有重要的意义——这类似于hibernate的延迟加载的机理——动态代理。

Extjs-4.2.1(二)——使用Ext.define自定义类的更多相关文章

  1. Extjs 学习总结-Ext.define自定义类

    本教程整理了extjs的一些基本概念及其使用,包括自定义类(Ext.define).数据模型.代理等.本节介绍使用Ext.define自定义类 使用Ext.define自定义类 1. 首先看看js中自 ...

  2. ExtJS 4.2 教程-03:使用Ext.define自定义类

    转载自起飞网,原文地址:http://www.qeefee.com/extjs-course-3-define-classes ExtJS 4.2 教程-01:Hello ExtJS ExtJS 4. ...

  3. ExtjS学习--------Ext.define定义类

    Ext类Class的配置项:(注:Extjs的 的中文版帮助文档下载地址:http://download.csdn.net/detail/z1137730824/7748893 ExtJS配置文件和演 ...

  4. Qt+QGIS二次开发:自定义类实现查询矢量数据的属性字段值(图查属性)

    在GIS领域,有两种重要的查询操作,图查属性和属性查图. 本文主要介绍如何在QGIS中通过从QgsMapToolIdentify中派生自定义类实现查询矢量数据的属性字段值(图查属性). 重点参考资料: ...

  5. cocos2dx lua 绑定之二:手动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一 ...

  6. ExtJS学习------Ext.define的继承extend,用javascript实现相似Ext的继承

    (1)Ext.define的继承extend 详细实例: Ext.onReady(function(){ //Sup Class 父类 Ext.define('Person',{ config:{ n ...

  7. Extjs学习笔记--(二)

    1.配置实用Extjs <link href="Extjs/resources/css/ext-all.css" rel="stylesheet" /&g ...

  8. ExtJs 学习之开篇(-)之define

    Ext.onReady(function(){    /**     * test1,声明一个类,定义类中的方法     */ Ext.define("demo.Demo",{   ...

  9. 无废话ExtJs 入门教程十二[下拉列表联动:Combobox_Two]

    无废话ExtJs 入门教程十二[下拉列表联动:Combobox_Two] extjs技术交流,欢迎加群(201926085) 不管是几级下拉列表的联动实现本质上都是根据某个下拉列表的变化,去动态加载其 ...

随机推荐

  1. .net System.Net.Mail 之用SmtpClient发送邮件 Demo

    private static bool sendMail() { try { //接收人邮箱 string SendTo = "XXXXX@163.com"; //抄送人邮箱 st ...

  2. MacBook Pro 的照相机在哪?

    用于拍照 用于录制视频

  3. Manifest文件简介

    每个Android项目都包含一个Manifest文件-Android Manifest.xml,它存储在项目层次中的最底层.Manifest可以定义应用程序及其组件和需求的结构和元数据. 它包含了组成 ...

  4. JavaScript学习笔记-数组(1)

    数组是值的有序集合.每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引.JavaScript数组是无类型的:数组元素可以是任意类型,并且同一个数组中的不同元素也可能有不同的类型.数 ...

  5. Windows系统 环境变量

    用户变量与系统变量 用户变量只对当前用户有效,而系统变量对所有用户有效.在检索命令时,系统变量会排在用户变量的前面.也就是说,如果两个地方都包含同一个命令,则优先执行系统变量指示路径下的命令. set ...

  6. linux 硬盘相关命令学习

    summary: 查看硬盘信息:几块硬盘,品牌,容量 查看分区信息 参考资料: Linux下查看磁盘分区命令详解: http://blog.chinaunix.net/uid-26119273-id- ...

  7. CCNA第一讲笔记

    园区网:一组连续的局域网(校园网.企业内部网) 园区网拓扑: 一层楼的PC连接到一台交换机(同一层的PC可以互联):一栋楼的每层的交换机连接到同一台交换机(整栋楼的PC可以互联):每栋楼的交换机连接到 ...

  8. excel 导入功能

    一:示例代码 //InputStream fis = new FileInputStream(tomcaturl+this.awardTask.getFileRoute());//可以通过上述方式获得 ...

  9. 配置ADB 工具 (Win7_64)

    ADB (Android Debut Bridge) ADB这个工具, 让我们可以用电脑来操纵手机 Android studio 安装好之后在SDK 中就有ADB 但是我们想使用它还需要配置它的环境变 ...

  10. 就要从SDG离职了

    在知乎上看到有个提问,你为什么从盛大离职.我八月份在盛大游戏实习之间,下个星期准备辞职迎接新的挑战.本文也将提到我在盛大实习的经历以及离职的原因.当然,不会涉及很多SDG内部的管理以及技术上的秘密. ...