Ext js 6 - Class System

来源:互联网 发布:手机淘宝怎样撤销投诉 编辑:程序博客网 时间:2024/05/01 01:59

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.CoolProxyMyCompany.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.createLogger.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 为这个新创建的类设置一个别名

一旦一个类创建完成,以下的postprocessors将会被执行

Postprocessor Description alias 在class manager中注册一个新的类,以及这个类的别名 singleton 如果在define方法中指定了singleton属性,则以单例的模式,创建这个类的实例 alertnateClassName 修改新创建类的别字 uses 导入将被使用的类,以及新创建的类

上面的过程,有的不会被运行,这取决于在定义类时define()方法中的配置。

现在你对如何创建一个类系统有一个基本的认识,我们将继承使用这此处理流程定义我们的类以及使用它们。

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 classvar 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()});// ORExt.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,它会等待所有的都加载完成后使用。

1 0
原创粉丝点击