ExtJS的class系统

 

      Ext JS是一个面向对象的类库,在EXT JS 4,类系统被完全重新设计并添加了很多新的特性,使得类的创建和扩展的能力变得更加强大。在整个框架中, Ext.ClassManager类管理字符串的类名称映射到实际类的对象。 一般不直接访问它,而是通过以下这些方法(方便记忆):
  • Ext.define: 是Ext.ClassManager类的create方法的简写,该方法负责一个新的Class的创建,此外,也可以重写已有类的属性和方法。
  • Ext.create: 是instantiate方法的简写,该方法用来创建已存在的类的实例。
  • Ext.widget: 它的完整形式是Ext.ClassManager类的instantiateByAlias方法,该方法可以通过类的别名来获取一个类的实例。
下面使用第一个方法Ext.define定义一个类Person,然后用Ext.create对其进行实例化:
Ext.define( "Person",{ //#1 
     name: '张三', //#2 
     age: 23,
     
     constructor: function(config) {  //#3 
            Ext.apply( this,config||{}); //#4 
           console.log( "I'm a new client" );
     }
});
var person1 = Ext.create( "Person"); //#5
console.log(person1.name);

var person2 = Ext.create( "Person",{ //#6
     name: '李四'
});
console.log(person2.name); 
person2.age = 12;     //#7
console.log(person2 .age);
 说明:
    #1: 给Ext.define传递一个字符串形式的参数作为类的名字,在这儿我们定义了一个Person类
    #2: 第二个参数是一个对象,定义类的属性和方法,这里定义了name和age两个属性值。
    #3: constructor这是一个特殊的方法,相当于java中的构造方法,在类被创建时ClassManager会自动调用,如果没有定义,它将会是一个空函数。
    #4: 在创建类实例的时候,我们通过参数config对象设置新值,config的内容应该是能够修改的类的属性,通过这种方式我们就可以在不同的类的实例中设置不同的属性值,如果我们没有设置任何参数,那新的实例将采用默认值。
    #5: 通过Ext.create方法创建类的实例,该方法的第一个参数是类的名称,在这儿采用默认值得方式创建实例person1。
    #6: 通过第二个参数给person2这个实例设置新的name属性值。
    #7: 通过对象实例修改实例的属性值。
 Person类定义完成后,新建一个HTML执行上面的代码。代码运行结果如下:
  ExtJS的class系统
     通过结果可以知道在每次创建类实例的时候将会执行constructor方法。当然如果我们得到了一个类的实例,也可以通过#7的方式修改实例的值。
1.  类的继承
      当我们使用Ext.define创建一个类的时候,我们应该记住,如果没有配置继承类,默认的他会继承Ext.Base类。在Ext library中,大部分的类都是继承自Ext.Base类,下面的截图是ExtJS中的button与model的继承关系。这表示button和model都具有Ext.Base中的属性和方法。
ExtJS的class系统
 在实际的类的定义中,我们往往需要继承其它的类而不是Ext.Base,这时就需要我们配置extend属性,这就会继承父类的所以的属性和方法。
Ext.define( "User",{
     extend: 'Ext.data.Model', //#1
     
     fields: [ //#2
            'id',
            'name'
     ]
});
var user = Ext.create( "User",{ //#3
     id: 001,
     name: '张三'
});
console.log(user.get("name")); //#4
 说明:#1: 首先创建一个类并继承自Ext.data.Model类,这样User就有了Model类的所以属性和方法。
   #2: 创建fields字段,这个字段可以根据需要添加任意数目的字段。
   #3: 创建一个User类的实例,通过第二个参数设置fields字段的值。
   #4: 输出数据,查看结果,这儿注意的是在User类中并没有定义get方法,所以该方法是继承得来的。
 
2.  处理器
在Ext JS中,每一个类都是Ext.Class类的一个实例,当使用Ext.define方法定义一个类的时候实际上是创建了一个Ext.Class的实例。按照API文档的描述,Ext.Class是一个由Ext.ClassManager使用的底层工厂,不宜直接使用。 如果您选择使用Ext.Class,你将失去命名空间, 混淆和依赖加载功能可通过Ext.ClassManager取得。也就说Ext.ClassManager仅仅只是一个工厂类,它并不是SupperClass,其它的所有Extl类继承自前面说过的Ext.Base,当我使用Ext.create方法的创建类时候,在Ext的后台其实是在运行的一系列的处理器(process)去进行类的创建。每个process完成创建类的过程中一个特定的任务。每一个处理器处理结束以后就执行下一个处理器,一直到处理器列表为空的时候就表明类创建完成。其中,处理器又分为前置处理器和后置处理器。
  • 前置处理器: 预处理器是在Ext.Class类的实例被执行之前运行的处理器,也就是说在类创建之前,预处理器有可能会改变类的属性状态等行为。
  • 在类被创建之后执行的process,例如类的单例,类别名等都是后处理器完成的。
       虽然ExtJS定义很多处理器,但是当不能满足我们的需求时我们也可以定义自己的处理器并把它添加到处理器队列中。通过下面的代码我们可以查看ExtJS中默认的预处理器和后处理器:
(function() {
     Ext.onReady(function() {
            var pre = Ext.Class.getDefaultPreprocessors(),
           post = Ext.ClassManager.defaultPostprocessors;
           
            console.log(pre);
            console.log(post);
     });
})();
 运行代码可以看到控制台输出如下
 
      通过上面的输出我们可以看到在ExtJS类系统中定义了一系列的前置处理器和后置处理器,共同完成了类的创建工作。把下面的输出转换为直观的图形表示如下。
ExtJS的class系统 这张图表明了在创建类的时候发生了什么,所有的前置处理器处理相关的信息为类的创建准备好条件,所有的后置共同完成类的后续处理。下面通过表格简要描述了各个处理器的功能和作用。
  • 前置处理器
 

className

This defines the namespace and the name of the class.

loader

This looks for the dependencies and if they don't exist already then it tries to load them.

extend

This inherits all the methods and properties from the superclass to the new class.

statics

This creates the defined static methods or properties for the current class.

inheritableStatics

This inherits the static methods or properties from the superclass, if applicable.

config

This creates the getters and setters for the configurations properties.

mixins

This inherits all the methods and properties from the mixin classes.

xtype

This defines the xtype for the new class.

alias

This sets the alias for the new class.

  • 后置处理器

alias

This registers the new class to the class manager and its alias.

singleton

This creates a single instance of the new class.

alternateClassName

This defines alternative names for the new class created.

uses

This imports the classes that will be used, along with the new class.

       在这些处理器中,不一定会每一个都会执行,这要看类的配置,例如,在类中没有配置依赖或者statics,那么相应的处理器就会被忽略。
 
3.  类的Mixins(混入)
        上面我们明白了类的继承,但有时候我们会有继承多个类的需求,这就需要使用到mixins processor(混入)了。如果在一个类中混入了多个类,那么这个类将拥有这些混入类的所有的属性和方法。
(function() {
     Ext.onReady(function() {
           Ext.define( "say",{
                cansay: function() {
                     console.log( "hello");
                }
           });
           
           Ext.define( 'CanSing', {
                sing: function() {
                    console.log("I'm on the highway to hell...");
                }
           });
           
           Ext.define( "user",{
                mixins: {
                     say: 'say',
                     sing: 'CanSing'
                }
           });
           
           var u = Ext.create( "user");
           u.cansay();
           u.sing();
     });
})();
 
       上面的代码首先定义了say和CanSing两个类,然后user类通过混入say和CanSing这两个类的方式拥有了cansay方法和sing方法。
 
4.  Configurations
       在ExtJS4中新增加的一个重要的特性就是configurations。有时我们需要输入参数通过set函数来改变类的属性值或者行为,ExtJS4提供了configurations预处理器来执行这种需要,只有在相应的属性配置到config配置项中,框架就会为每个属性自动生成get,set,apply和reset四个函数。
Ext.define( "MyApp.data.Invoice",{
     config : {            //Step 1
         client   : '',
         tax      : 0.083,
         subtotal : 0,
         total    : 0
     },
    constructor  : function(config){
     var me = this;

     me.initConfig(config);      //Step 2
    }
});

var invoice = Ext.create( "MyApp.data.Invoice",{
  client  : "Tuxtux Inc",
  subtotal  : 100,
  total    : 108.3
});

console.log(invoice.getClient());
console.log(invoice.getSubtotal());
console.log(invoice.getTax());  // 0.83
console.log(invoice.getTotal());

invoice.setTax(0.16);

console.log(invoice.getTax());  // 0.16
说明:Step 1: 首先,我们需要定义一个预处理器config,它允许我们配置一个由我们所需要的属性所组成的对象,也可以为每一个属性设置默认属性值。
Step 2: 我们在构造函数中利用 initConfig方法把config参数初始化到config配置项的属性中。initConfig方法是在Base类中定义的,所以每一类都拥有这个方法。
       在执行完上面两个步骤以后,我们就可以用get方法取到相应的属性的值,当然我们也可以使用set来改变相应的属性值。

5.  静态方法与属性
      静态方法是属性类class而不是属于类的实例,因此,我们能够直接使用类的静态方法而不用创建类的实例。ExtJS4中,类的静态方法和静态属性是通过statics预处理器来执行。所以在定义类的时候,在statics配置项定义的属性或方法就成了静态属性或方法,然后就可以直接通过类来进行调用。示例如下:
Ext.define( "User",{
     statics: {
           myname: 'zhangsan',
           
           say: function() {
                 var str = "My name is " + this.myname;
                console.log(str);
           }
     }
});

User.say()
 
6.  单例Singleton
       定义为singleton的类只能实例化一次,Ext通过singleton后处理器来完成singleton的定义。singleton类一般用在程序的公共常量,如应用路径,图片路径,系统配置等。在这里需要特别注意的是配置为 singleton的类不能通过Ext.create等来进行实例化。
Ext.define( "MyApp.Constants",{
  singleton     : true,     //Step 1

  BASE_PATH  : "/myapp", //Step 2
  ATTEMPTS  : 5,
  TIMEOUT    : 6000
});
console.log(MyApp.Constants.BASE_PATH);
//Ext.create("MyApp.Constants"); //Throws an error
 
7.  别名Alias
      Alias也是一个后处理器,当一个类定义了alias配置项以后,class manager会负责映射一个alias name到对应的实际class对象。 Alias特性在采用xtype创建组件的时候非常有用,也是其主要的应用场所。
Ext.define( "MyApp.abstract.Panel",{
  extend   : "Ext.panel.Panel",
  alias  : "widget.mypanel",

  title  : "Abstract panel",
  html  : "Main content"
});

Ext.onReady( function(){

  Ext .create("widget.mypanel" ,{ //Option 1
    renderTo  : Ext .getBody()
  });

     //Option 2
  Ext .ClassManager.instantiateByAlias("widget.mypanel" ,{
    renderTo  : Ext .getBody()
  });

     //Option 3
  Ext .ClassManager.instantiate("widget.mypanel" ,{
    renderTo    : Ext .getBody()
  });

  var win = Ext .create("Ext.window.Window" ,{
    title  : "Window",
    width    : 350,
    height  : 250,
    items    : [{
           xtype : "mypanel"  //Option 4
    }]
  });
  win.show();

});
       首先,我们在定义类的时候使用alias属性便可以为这个类设置一个别名,在这里,使用widget前缀表明我们创建的是一个组件类。带别名的类定义完成以后,共有四种利用别名来使用组件类的方法。
  • 使用Ext.create方法,我们不但可以类的全称也可以使用类的别名来创建类实例
  • 使用Ext.ClassManager.instantiateByAlias方法来创建类的实例
  • 用Ext.ClassManager.instantiate方法完成实例创建,这种方法实际上是跟create是一样的。
  • 用xtype属性类实例化组件,使用这种方式的时候不需要widget前缀。widget是一个Ext标识,表明我们创建的是一个component组件,而xtype只能初始化组件,所以假定需要xtype初始化的都是有widget前缀的。
需要特定注意的是,xtype属性只能用在component和widgets。
 
 
 
 
 
 

 

你可能感兴趣的:(ExtJs)