Ext js 6 - Class System
2016-08-10 17:43
239 查看
Class System
Overview
我们可以搭建测试代码, 不需要使用Sencha cmd<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <link href="./build/classic/theme-classic/resources/theme-classic-all.css" rel="stylesheet" /> <script src="./build/ext-all.js"></script> <script> Ext.define("My.sample.Person", { name: 'Unknow', constructor: function(name){ if (name) { this.name = name; } }, eat: function(foodType){ alert(this.name + " is eating: " + foodType); } }) var bob = Ext.create("My.sample.Person", 'Bob'); bob.eat("Salad"); </script> </head> <body> <div id="helloWorldPanel"></div> </body> </html>
命名规则
类名
类名只可以包含字母和数字字符,使用数字是允许的,但不鼓励使用,除非这个类名,要表示的是专有名词,比如base64. 不能使用下划线,连接字符,或其它非non-alphanumeric
MyCompany.useful_util.Debug_Toolbar 这是不允许的
MyCompany.util.Base64 可以使用
类名应该在一个顶级命名空间(唯一)之后,比如
MyCompany.data.CoolProxy MyCompany.Application
开始的命名空间和实际的类名都应该为驼峰命名法(每个单词首字母大写), 其它的都应该小写
MyCompany.form.action.AutoLoad
实际类名如果有缩略词,也应该遵循驼峰命名法, 比如下面的情形
Ext.data.JSONProxy应该写为Ext.data.JsonProxy
MyCompary.parser.HTMLParser写为MyCompany.util.HtmlParser
MyCompany.server.HTTP写为MyCompany.server.Http
源文件
类的名字也就表示了它源文件的的路径。所以每个类必须对应一个源文件,比如* Ext.util.Observable is stored in path/to/src/Ext/util/Observable.js
* Ext.form.action.Submit is stored in path/to/src/Ext/form/action/Submit.js
* MyCompany.chart.axis.Numeric is stored in path/to/src/MyCompany/chart/axis/Numeric.js
path/to/src表示你应用程序的目录,所有的类都应该保存在相同的目录下,并且采用这种方式,方便开发,维护和部署。
方法和变量的命名
这跟类名的命名类似。只能是字母和数字。方法和变量必须为camelCased(小写开头). 这同样适用于缩略词,比如json, html.
Example
以下是有效的方法名encodeUsingMd5()
getHTML() 应该为getHtml()
getJSONResponse()应该为getJsonResponse()
parseXMLContent()应该为getXmlContent()
以下是有效的变量名
isGoodName
base64Encoder
xmlReader
httpServer
属性
类的属性的命名,跟类,变量,方法的命名是一样的。除非它们为静态常量类的静态属性命名,则全部为大写
Ext.MessageBox.YES = “Yes”
Ext.MessageBox.NO = “No”
MyCompany.alien.Math.PI = “4.13”
类的声明
Ext.define用于创建一个类, 这个方法创建的类,都是Ext.Base的子类, 所以创建的子类都有, callParent, callSuper, initConfig,getConfig, setConfig, 等方法。 以下是它的基础用法
Ext.define(className, members, onClassCreated);
className: 字符串表示的类的名字
members: 一个对像,以键和值的方式,表示这个类的成员(变量和方法)
onClassCreated 是一个可选的回调函数。当定义的这个类的加载完它的依赖,并且这个类完全创建好后,调用。对于
异步来说,在很多情况下这非常有用。
Example
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 bob = Ext.create('My.sample.Person', 'Bob'); bob.eat("Salad"); // alert("Bob is eating: Salad");
**Note:我们也可以通过new My.sample.Person创建这个类的实例,但是推荐使用Ext.create方法。 因为它可以让你使用动态加载,
而new则不可以。**
Configuration
新创建的类会从Ext.Class继承一个专有的config属性. Ext.Class主要用于描述一个类,比如alias, config, xtype等。* config属性指定的配置独立于新建类的其它成员,它完全封闭在config属性中
* 新建类会为每一个config配置创建一个Getter和Setter方法。前题是这些方法没有明确的被定义在新建的类中
* 自动创建的setter方法在设置配置时,会调用apply方法(如果有在类中定义). 如果你在设置新的配置值时,需要重写这个apply方法。如果apply
方法,不返回值,则自动生成的setter方法,不设置这个配置值。同样,还有一个update的方法,这个方法在配置值被设置了不同的值时,被调用。
apply和update的参数为一个新值和一个旧值
对于Ext class的配置,既你定义的类扩展于Ext Component,我们不需要手动的调用initConfig方法,可以直接使用config属性。但对于我们自己创建的类,它会继承Ext.Base
initConfig()依然需要被调用, 否则不会自动生成setter和getter方法, 可以查看Ext.Class config的描述.
Example
Ext.define('My.own.Window', { extend: 'Ext.Component', /** @readonly */ isWindow: true, config: { title: 'Title Here', bottomBar: { height: 50, resizable: false } }, 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) { if (!this.bottomBar) { //如果当前没有设置bottomBar配置,则通过Ext.create创建一个自定义的子类 //这样它有可以从Ext.Base中继承setConfig, 也可以获得子配置 //即bottomBar保存的是一个Ext的对像 return Ext.create('My.own.WindowBottomBar', bottomBar); } else { //查看Ext.Base中的setConfig, 因为当前的bottomBar为一个Ext Base的子类的对像 //所以可以直接调用它的setConfig, 改变它的值,而不用返回一个新值 this.bottomBar.setConfig(bottomBar); } } } }); /** A child component to complete the example. */ Ext.define('My.own.WindowBottomBar', { config: { height: 10, resizable: true } });
以下是代码将看到如何使用configuration创建一个对像
var myWindow = Ext.create('My.own.Window', { title: 'Hello World', bottomBar: { height: 60 } }); //由于My.own.Window继承于Ext.Component, 所以它会将创建myWindow中的传递的配置,应用于config中, //如果是只继承于Ext.Base, 则下面的内容输出undefined, Configuration只能通过setTitle()和getTitle()来使用,也不能使用myWindow.title="Hello World"; 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 }); alert(myWindow.getBottomBar().getHeight()); // alerts 100
Statics
静态的成员可以定义在statics config中xt.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 } }); 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"
错误处理与调试
Ext js包含了很多有用的特性,帮助我们调试和处理错误你可以使用Ext.getDisplayName() 获得任何方法的显示名称, 然后可以应用于抛出错误中.
throw new Error('['+ Ext.getDisplayName(arguments.callee) +'] Some message here');
如果Ext.define()中定义的类,某个方法抛出了一个错误。那么可以在基于Webkit的浏览器的调用栈,看到这个类和方法名.
Ext js常用类
Ext
Ext是一个全局的单例对像,它封装了Sencha库中的所有类,单例以及有用的方法,许多常用的工具函数定义在Ext,它同样提供了许多其它常用类的快捷键。
以下让我们看看Ext中定义的方法和属性:
application方法
许多应用都是通过Ext.application进行初始化。这个函数加载Ext.app.Application类,并且在页面加载完成之后开始应用程序。Ext.app.Application是一个类,表示整个的应用。
Ext.application({ name: 'MyApp', extend:'MyApp.Application', launch: function() { } });
以上的代码创建了一个全局的变量MyApp.应用程序中所有的类将会在这个唯一的命名空间下,这样可以避免与全局变量的冲突。
define方法
用于创建或覆盖一个类。它接受三个参数,第一个为类名,它为字符串类型,第二个为创建类需要使用到的数据,第三个为创建完后,执行的回调函数.,因为创建类时,会动态加载依赖的类,这时回调函数就有用了。
Ext.define(name, data, callback)
以下创建一个 Car class
Ext.define('Car', { name: null, constructor: function(name) { if (name) { this.name = name; } }, start: function() { alert('Car started'); } });
也可以创建一个继承类
Ext.define('ElectricCar', { extend: 'Car', start: function() { alert("Electric car started"); } });
如果你想要替换一个基础类,你可以使用define覆盖原有的方法。
Ext.define('My.ux.field.Text', { override: 'Ext.form.field.Text', setValue: function(val) { this.callParent(['In override']); return this; } });
如果你想创建的类,它是一个单例类,你可以使用 singleton属性,它定义在Ext.Class类中
Ext.define('Logger', { singleton: true, log: function(msg) { console.log(msg); } }); //可以直接使用这个类,而不需要使用Ext.create Logger.log("hello")
create方法
你可以使用以下的方式创建一个类的对像var myCar = Ext.create('ElectricCar',{ name: 'MyElectricCar' });
如果Ext.Loader是允许的,那么 Ext.create 会在ElectricCar这个类不存在的情况下,自动下载相应的Javascript文件。默认情况下,Ext.Loader
是允许的,你也可以配置文件中将Ext.Loader设置为false.
你也可以使用new关键词创建一个实例,但是,如果这个类不存在时,它不会自动加载对应的Javascript文件。
var myCar = new ElectricCar('MyElectricCar');
onReady方法
在页面加载完成时,dom可操作时,调用Ext.onReady(function(){ new Ext.Component({ renderTo: document.body, html: 'DOM ready!' }); });
在许多情况下,你不需要使用onReady方法。只在一些特定的少有的情况下才需要使用。如果你之前有过jQuery编程,请不要像jQuery那样
经常使用onReady方法
$( document ).ready().
widget方法
当你定义在一个类时,你可以给它一个简短的别名。比如Ext.panel.Panel的一个别名为widget.panel.当你定义了一个widget, 不是在类中指定别名,你就可以使用xtype表示一个这个类了
当一个container在执行前,没有创建一个组件的时例时,xtype可以用来指定widget的名称,这非常有用。
Ext.widget,它接受一个xtype字符串,而不是类名,用来创建一个widget.
比如,在没有使用widget方法时,创建一个类的时候Ext.panel.Panel的对像
Ext.create('Ext.panel.Panel', { renderTo: Ext.getBody(), title: 'Panel' });
然而,你可以使用更简单的方法,创建它的实例
Ext.widget('panel', { //panel为xtype renderTo: Ext.getBody(), //html body title: "Panel" })
以下是使用别名的方法创建一个相同的对像
Ext.create('widget.panel', { renderTo: Ext.getBody(), title: 'Panel' });
getClass方法
如果一个类是通过Ext.define定义的,则可以使用getClass方法,返回一个对像的类名。如果类不是通过Ext.define定义的,则返回的为空。var button = new Ext.Button(); Ext.getClass(button); // returns Ext.Button
getClassName方法
根据引用或者类的对像,返回类的名字(字符串)Ext.getClassName(Ext.Button); //returns "Ext.Button"
Ext.Base
它是所有Ext的基类。 Ext中所有的类都是继承于Ext.Base. 在这个类中的所有原型和静态成员,都会被其它类所继承。Ext.Class
这个类是一个低级的工厂类,当在使用Ext.ClassManager创建一个类时使用这个工厂函数。所以,在你的代码中不要直接使用它,而应该使用Ext.define()
Ext.ClassManager
它用于管理所有的类,并且处理字符串类名到实际类的映射。它通常会在以下几个函数类使用Ext.define
Ext.create
Ext.widget
Ext.getClass
Ext.getClassName
Ext.Loader
这个类主要用来动态加载依赖,正常的,使用快捷方法Ext.require替代。当你定义一个类时,最佳的实践时,指定要加载的组件,比如Ext.require(['widget.window', 'layout.border', 'Ext.data.Connection']);
如果你需要某个空间下的所有组件/类,可以使用通配符
Ext.require(['widget.*', 'layout.*', 'Ext.data.*');
如果要排除,可以使用以下方式
Ext.exclude('Ext.data.*').require('*');
通过这种方式,加载的类是通过异步方式。如果你在定义类时,没有指定加载的类时,则当使用Ext.Create创建这个类的实例时,如果类没有加载时
,类文件将被以同步的方式加载(停止运行,等待文件下载完成)。这会影响一点性能。所以,当你定义你的类时,最好通过Ext.require指定你要加载的类
Class创建过程
在Ext js中每一个class都是Ext.Class类的实例,当我们使用define定义一个类时,实际上我们创建了一个Ext.Class类的实例。依据我们上面讲的,Ext.Class类是一个工厂函数。这就是说,我们创建的新类,它不是继承于Ext.Class. 之前我们讲过,所有的类都是继承于Ext.Base. 所以,我们在使用Ext.create方法时,Ext在幕后运行了很多的处理过程。每一个处理过程在创建一个类时都有特定的目的。
一个处理过程可以为异步,也可以为同步,比如,有一个处理过程,运行到它时,用来加载我们创建的新类所需要的所有依赖(依赖还没有被加载时)。当这个过程运行完后,下一个处理过程会被执行,直到整个任务链表为空,然后一个新的类被创建。
一个preprocessor是在创建Ext.Class实例之前运行的过程。换句话说,就是在创建一个新类之前运行的过程。它所对应的每一个过程,都能改变我们类的行为。
一个postprocessor是在我们创建完一个类之后运行。比如创建一个类的单例,或者给我们的定义一个别名,等等。
在Ext库中,已经定义了很多的处理过程,但我们也可以定义过程,并且添加到处理队列中。
现在的问题是,这里有哪此过程?它们是用来做什么的。我们可以通过以下的几行代码,打印所有的预处理和后处理过程.
var pre = Ext.Class.getDefaultPreprocessors(); var post = Ext.ClassManager.defaultPostProcessors(); console.log(pre); console.log(post);
Output:
["className", "loader", "extend", "privates", "statics", "inheritableStatics", "platformConfig", "config", "cachedConfig", "mixins", "alias"] ["alias", "singleton", "alternateClassName", "debugHooks", "deprecated", "uses"]
下面的图片表示了整个的处理流程
上图显示在创建一个类时的所有经过。所有的preprocessors都在创建类之前运行,修改最终创建的类。而postprocessors则在类已经准备被使用时运行。
举例来说,loader 过程主要是用来处理依赖,如果需要的依赖还没存在,则它以同步的方法(阻此之后的代码执行)加载依赖的js文件。在所有的依赖准备好之后,才把控制权传递给Ext.Class,让它继承执行接下来的处理程序。接下来的处理过程是extend, 它主要负责将superclass(加载过的依赖文件, 父类)中原型方法和属性复制给要创建的子类。
以下这个表格简单的描述了各预处理过程。
Preprocessors | Description |
---|---|
className | 根据define方法中的字符串,定义类的空间和名字 |
loader | 用来查找依赖,如果依赖不存在,则尝试加载它们 |
extend | 从加载的父类中,继承原型中的方法和属性 |
statics | 为创建的当前类,定义静态的方法和属性 |
inheritableStatics | 如果可以,从父类中复制static方法 |
config | 为可配置的属性创建getter和setter方法 |
mixins | 从mixins属性中指定的类,继承这些类中指定的方法和属性 |
alias | 为这个新创建的类设置一个别名 |
Postprocessor | Description |
---|---|
alias | 在class manager中注册一个新的类,以及这个类的别名 |
singleton | 如果在define方法中指定了singleton属性,则以单例的模式,创建这个类的实例 |
alertnateClassName | 修改新创建类的别字 |
uses | 导入将被使用的类,以及新创建的类 |
现在你对如何创建一个类系统有一个基本的认识,我们将继承使用这此处理流程定义我们的类以及使用它们。
Mixing many classes
目前为此,我们只学习了简单的继承,但我们也可以使用mixins处理流程,模似多重继承。它的概念非常简单:我们可以将多个类,混合到一个类。最后,新的类可以从所有的被混合的类访问它们的属性和方法。一个公司中的职业变化依赖于组织关系,一个秘书(Secretary)根据她所负责的经理或会计师,执行不同的职责。所要我们需要将每个职业的职责独立出来。以下是它们的关系图
//将每个职责,定义成类 Ext.define('Myapp.sample.tasks.attendPhone',{ answerPhone:function(){ console.log( this.name + ' is answering the phone'); } }); Ext.define('Myapp.sample.tasks.attendClient',{ attendClient:function(clientName){ console.log( this.name + ' is attending client: ' + clientName); } }); Ext.define('Myapp.sample.tasks.attendMeeting',{ attendMeeting:function(person){ console.log( this.name + ' is attending a meeting with ' + person); } }); Ext.define('Myapp.sample.tasks.superviseEmployees',{ superviseEmployee:function(supervisor, employee){ console.log( supervisor.name + ' is supervising : ' + employee.name + ' ' + employee.lastName); } });
以下,我们定义每个职业类
//基础类 Ext.define('Myapp.sample.Employee',{ name: 'Unknown', lastName: 'Unknown', age: 0, constructor: function (config){ Ext.apply( this, config || {} ); console.log('class created – fullname:' + this.name + ' ' + this.lastName); }, checkAge:function(){ console.log( 'Age of ' + this.name + ' ' + this.lastName + ' is:' + this.age ); }, work: function( task ){ console.log( this.name + ' is working on: ' + task); } }); //秘书类 Ext.define('Myapp.sample.Secretary',{ extend:'Myapp.sample.Employee', mixins:{ answerPhone: 'Myapp.sample.tasks.attendPhone' }, constructor: function (config){ Ext.apply(this, config || {}); console.log('Secretary class created – fullname:' + this.name + ' ' + this.lastName); } }); //会计类 Ext.define('Myapp.sample.Accountant',{ extend:'Myapp.sample.Employee', mixins:{ attendClient: 'Myapp.sample.tasks.attendClient', attendMeeting: 'Myapp.sample.tasks.attendMeeting' }, constructor: function (config){ Ext.apply(this, config || {}); console.log('Accountant class created – fullname:' + this.name + ' ' + this.lastName); } }); Ext.define('Myapp.sample.Manager',{ extend:'Myapp.sample.Employee', mixins:{ attendClient: 'Myapp.sample.tasks.attendClient', attendMeeting: 'Myapp.sample.tasks.attendMeeting', supervisePersons:'Myapp.sample.tasks.superviseEmployees' }, constructor: function (config){ Ext.apply(this, config || {});//this.name= config.name; console.log('Manager class created – fullname:' + this.name + ' ' + this.lastName); }, supervise: function(employee){ console.log( this.name + ' starts supervision '); this.mixins.supervisePersons.superviseEmployee(this, employee); console.log( this.name + ' finished supervision '); } });
在这里,我们创建了三个类(Secretary, Account, and Manager). 每个类都继承于Employee, 每一个类都是继承于Employee类,并且通过mixins继承其它的类方法。以下是这个类的使用
// Usage of each class var patricia = Ext.create('Myapp.sample.Secretary', { name:'Patricia', lastName:'Diaz', age:21 } ); patricia.work('Attending phone calls'); patricia.answerPhone(); var peter = Ext.create('Myapp.sample.Accountant', {name:'Peter', lastName:'Jones', age:44 } ); peter.work('Checking financial books'); peter.attendClient('ACME Corp.'); peter.attendMeeting('Patricia'); var robert = Ext.create('Myapp.sample.Manager', {name:'Robert', lastName:'Smith', age:34 } ); robert.work('Administration of the office'); robert.attendClient('Iron Tubes of America'); robert.attendMeeting('Patricia & Peter'); robert.supervise(patricia); robert.supervise(peter);
使用mixinConfig属性
使用mixinConfig属性,使得被混入的类,可以提供before和after勾子函数,而这些可以不用在新类中定义(即,可以为新类中的方法, 提供这个方法执行和执行后的函数)。简单的理解就是,在mixinConfig中的before和after中定义的方法,可以在这个对应的方法调用时执行。所以mixinConfig中的设置相当于一个监听器(观察者), 当一个附加的函数被调用时,将执行这个方法所对应的before和after对应的方法。
//定义一个监听器,或者将被混入的类 Ext.define('Myapp.sample.tasks.attendCellPhone',{ extend: 'Ext.Mixin', /* answerCellPhone是一个监听的函数,当这个函数执行时 分别调用对应的cellPhoneRinging和finishCall */ mixinConfig:{ before:{ answerCellPhone:'cellPhoneRinging' }, after:{ answerCellPhone:'finishCall' } }, cellPhoneRinging: function(){ console.log( 'cell phone is ringing you may attend call'); }, finishCall: function(){ console.log( 'cell phone call is over'); } });
以下的代码混合上面的类
Ext.define('Myapp.sample.Secretary',{ extend:'Myapp.sample.Employee', mixins:{ answerPhone: 'Myapp.sample.tasks.attendPhone', util:'Myapp.sample.tasks.attendCellPhone' }, constructor: function (config){ Ext.apply(this, config || {});//this.name= config.name; console.log('Secretary class created – fullname:' + this.name + ' ' + this.lastName); }, answerCellPhone:function(){ console.log( this.name + ' is answering the cellphone'); } });
在Ext库中,Ext.util.Observable, Ext.util.Floating, Ext.state.Stateful都可以被认为是mixins, 每一个类都只负责特定的事情。在一个大型的应用编码前,我们最好对应用程序的结构进行组织。
Singleton Class
一个singleton class 只能实例化一次。Ext允许我们通过一个postprocessor(过程),就能非常简单的创建一个singleton class.如果我们想要一个类为singleton, 我们只需要指定singleton属性为true. 它就可以打开相应的后处理过程(postprocessor).
Ext.define('Myapp.CompanyConstants',{ singleton: true, companyName: 'Extjs code developers Corp.', workingDays: 'Monday to Friday', website: 'www.extjscodedevelopers.com', welcomeEmployee: function (employee){ "Hello " + employee.getName() + ", you are now working for " + this.companyName; } });
以上这个类,在我们的应用程序中,将只有一个实例。 我们不在需要使用 Ext.create创建这个类的实例,我们可以通过以下方式调用
alert( Myapp.CompanyConstants.companyName ); var patricia = Ext.create('Myapp.sample.Employee', { name:'Patricia', lastName:'Diaz', age:21, isOld:false }); console.log(Myapp.CompanyConstants.welcomeEmployee(patricia));
Aliases
一个alias是一个类的简短名称, Ext.ClassManagers 将后为实际的类,添加一个别名。通常,一个别名为都为小写这个特性在使用xtype创建widgets时非常有用。比如
Ext.define('Myapp.sample.EmployeePanel',{ extend: 'Ext.panel.Panel', alias: 'widget.employeePanel', alternateClassName: 'mycustomemployeepanel', title: 'Employee Panel', html: 'Employee content here..!' });
在上面的代码中,我们通过alias创建了一个简短名称。我们也使用了widget作为前缀,表明,我们正在创建一个组件。一个组件的类可以为window, grid, or panel.
当然,在这个类中,我们也定义了alternateClassName属性,它让我们为新的类定义了一个别名。这个属性可以是一个字符串,或者是一个数组对像(多个别名), [‘employeepanel’,’customEmployeePanel’, ‘employeeboard’].
在Ext JS中,使用以下的别名,表示对应的空间
feature: This is used for Grid features
plugin: This is used for plugins
store: This is used for Ext.data.Store
widget: This is used for components
现在,让我们使用alias 创建一个类
Ext.onReady (function(){ Ext.create('widget.employeePanel',{ title: 'Employee Panel: Patricia Diaz...', height:250, width:450, renderTo: Ext.getBody() }); });
也可以使用alternateClassName:
Ext.onReady (function(){ Ext.widget('employeePanel',{ //using the xtype which is employeePanel title: 'Employee Panel: Patricia Diaz...', height:250, width:450, renderTo: Ext.getBody() }); });
让我们解释下整个过程,我们先定义了一个Myapp.sample.EmployeePanel,它继承了Ext.panel.Panel. 因此这个类是一个widget, 所以我们习惯性的给它的alias命名为widget.employeePanel. 如我们之前所说的, Ext.ClassManager会处理我们新创建这个类的声明(在内部,使用preprocessors和postprocessors) ,为之后的使用将定义/映射这个alias name. 所以,当我们创建一个Myapp.sample.EmployeePanel的实例时, Ext JS 将知如何处理和执行代码。
另外,我们也可以使用其它的方法引用这个新的类
Ext.ClassManager.instantiateByAlias("widget.employeePanel",{ renderTo: Ext.getBody() }); // OR Ext.createByAlias("widget.employeePanel",{ renderTo: Ext.getBody() });
Ext.createByAlias只是Ext.ClassManager.instantiateByAlias的一个快捷方式。同样,我们也可以使用xtype来引用一个新类
var win = Ext.create("Ext.window.Window",{ title: "Window", width:350, height:250, items: [{ xtype: "employeePanel" }] }); win.show();
按需加载类
当我们开发一个大型的应用时,性能是非常重要的。我们只需要加载我们所需要的;这意味着,如果我们的应用程序有很多的模块,我们应当将它们独立出来到各个包中,然后单独加载。从 Ext JS 4开始, 我们可以按需要,动态加载类和文件。所以我们可以在每个类中配置依赖,然后Ext 库后加载它们.
你需要知道使用loader对于开发模式非常有用,因为loader把一个一个的包含所有类,这使得我们可以调试代码。可是,不推荐在产品环境中加载所有的类。而应该创建这些类的包,然后按需要加载它们
* 一个文件只定义一个类
* 类的名称应当跟Javascript的文件名称一致
* 类的空间名称应该跟文件夹的结构匹配。比如,如果我们定义了一个MyApp.customers.controller.Main, 我们应该在MyApp/customers/controller下创建一个Main.js文件
允许加载器
loader 系统的enabled or disabled依赖于我们在html中引入的Ext文件。如果我们导入的是extjs/build文件夹下的ext-all or ext-all-debug文件, loader会被禁止使用,因为所有的Ext库已经被加载了。如果是extjs目录下的ext-all 或者ext-all-debug文件,则loader是enabled, 因为这此只有核心类被加载。如果我们需要使用loader有效, 我们应该在JS文件的开头,写入如下的代码
Ext.Loader.setConfig({ enabled: true });
上面的代码,允许我们按需要加载类。即在创建一个类时,有一个preprocessor用来加载还不存在的类。
为了开始加载类,我们需要设置这个类所有的路径。我们可以有两种方法,我们可以使用Loader的setConfig方法,并定义paths属性,如下所示
Ext.Loader.setConfig({ enabled:true, paths:{ MyApp:'appcode' } });
paths属性接受一个对像,它包含了我们应用程序的root namespace 和在这个命名空间下,所有类所在的目录。所以在上面的代码中,当我们引用Myapp, Ext JS将会查找appcode/ 文件夹。我们也可以在这里添加许多其它的路径。
一旦我们正确配置了loader, 我们可以使用require加载我们的类
Ext.require([ 'MyApp.Constants', 'MyApp.samples.demoClass' ]);
require会为我们创建一个script tag. 在所有的文件加载完成后,onReady事件会被触发。然后在onReady的回调函数中,我们可以使用所有加载完的类。
如果我们在require调用之后, 直接使用这些类,我们会获得一个error, 这是因为类还在下载和创建,它们还不存在。这也是为什么我们需要使用onReady,它会等待所有的都加载完成后使用。
相关文章推荐
- Ext JS 6.5.3 Official Documents — Class System
- 流行的AJAX框架对比:jQuery,Mootools,Dojo,Ext JS
- Ext JS
- Ext JS3.3.0刚出不久今天就匆忙更新到了Ext JS3.3.1,改动不多关系却很大..
- Ext JS 4倒计时:动态加载和新的类系统
- Ext JS 4倒计时:图形和图表
- 透视Ext JS 4类背后的机制与特点(中)
- 质的飞跃,Ext JS 4 Beta1发布,Grid同时处理百万数据成为现实(下载)
- 期待已久的Ext JS 4.0正式版发布了
- Ext JS 4.0.2发布!Ext JS 3.4 支持IE9!
- Ajax 框架_几种流行的 Ajax 框架 jQuery、Mootools、Dojo、Ext JS比较
- ext js 常见开发报错总结
- MyEclipse安装Ext JS和jQuery自动提示功能
- Ext js
- 透视Ext JS 4类背后的机制与特点(上)
- Ext JS 4.1 Beta 3 发布
- Ext JS下载及配置
- 围绕Ext JS 2.0的IDE、插件和工具 by Jack Slocum
- Ext JS 4.1.1 RC1 发布
- Ext JS 4.1.1 RC2发布