ExtJS学习之路第三步:理解引擎之下,ExtJS4中的类

写写就发现,有些代码不查查源头,不明白是怎么回事?搜到这篇文章觉得还是收益匪浅,更容易读懂代码。

Classes in Ext JS 4: Under the hood

Countdown to Ext JS 4: Dynamic Loading and New Class System[官网]

整理如下:

简单回顾一下,新的Class System (类系统),使我们能够这样定义类:

Ext.define(‘Ext.Window‘, {
    extend: ‘Ext.Panel‘,
    requires: ‘Ext.Tool‘,
    mixins: {
        draggable: ‘Ext.util.Draggable‘
    },    
    config: {
        title: "Window Title"
    }
});

这里,我们建立一个Ext.Window类的稍微简化版本。设置Window是Panel的子类,宣称需要Ext.Tool类,以及混合Ext.util.Draggable类的的某些功能。
让我们一句一句分析。‘extend‘声明你所期望的--Window必须是Panel的子类。
‘requires‘声明意味着命名类-Ext.Tool必须在Window类被视为可用之前[即将用]就已经存在。如果你用SeaJS的require话就明白时机啦,简单说就是Window要应用了,Ext.Tool必须在。
‘mixins‘这个在SASS(CSS预处理器)中有应用。在ExtJS4中,‘minxin‘(混合声明)是个全新的概念。一个mixin仅仅是一组函数(有时候是一组属性)被合并成到一个类中。比如,Ext.util.Draggable类中有个‘startDragging‘的功能,这就被复制到Window类中,我们能在Window的实例中应用‘startDragging‘功能。

定义startDragging方法:

Ext.define(‘Ext.util.Draggable‘, {
    startDragging: function() {
        console.log(‘started dragging‘);
    }
});

实例化

var win = Ext.create(‘Ext.Window‘);
win.startDragging(); //"started dragging"

   当一个类需要继承多个特性时,Minins就非常有用啦!而这对传统的单继承机制来说不易。例如,Ext.Windows是一个可拖动的组件,比如有Sliders,Grid headers和其他非常多的UI元素。因为这种动作发生在不同的地方,把这种拖拽行为归到单独一个父级类是不可行的。因为并非所有这些UI元素都以个共同的父级类。创建一个可团拽的Minxin解决了这个问题,仅需几行代码现在任何元素都可以变为可拖动的。

  最后一个新的功能块,是‘config‘配置。ExtJS中的大多数类都需要配置参数,其中很多在运行时改变。上面的例子中,我们声明了Ext.Window有个‘title‘配置,默认值是‘Window Title‘。通过上面的这种设置,我们免费得到4种方法,getTtiel,setTitle,resetTitle,applyTitle.

getTitle – 返回当前title值
setTitle – 设置新的title
resetTitle – 重置title值,此处为‘Window Title‘
applyTitle – 这是一个模板方法,你可以选择定义。当setTitle触发的时候,applyTitle触发。

applyTitle功能是当title改变时,调用其它需要改动的逻辑。比如:当更换一个title的时候我们可能想更新某个DOM元素。

Ext.define(‘Ext.Window’, {
    //..as above,   
    config: {
        title: ‘Window Title‘
    },    
    //updates the DOM element that contains the window title
    applyTitle: function(newTitle) {
        this.titleEl.update(newTitle);
    }
});

这种方式节省了大量的时间和代码,同时提供所有configuration配置选项一致的API-双赢。

深入研究

为了实现这神奇的功能,ExtJS 4引入4个新类。
Ext.Base-所有的类都继承自Ext.Base.它为所有类提供基本的低级别的功能。
Ext.Class-产生新类的工厂。
Ext.ClassLoader-负责确认class可用,如果页面上不存在,加载他们。
Ext.ClassManager-揭开类创建的序幕和管理依赖关系
这些在幕后齐心协力,大部分时间当你定义和使用类的时候,你不需要知道什么被调用了。常用的两个方法是Ext.define和Ext.create,在引擎中都触发Ext.ClassManager,这反过来又利用其它三个类把一切融合在一起。
Ext.Class和Ext.Base的区别是非常重要的。Ext.Base是顶层的父类,它定义了每个类,每个类都继承自Ext.Base在某些时候。Ext.Class代表类本身,每一个你定义的类都是Ext.Class的实例,并且是Ext.Base的子类。
为了说明这一点,假设我们创建MyClass的类,它并不扩展其他类。

Ext.define(‘MyClass‘, {
  someFunction: function() {
    console.log(‘Ran some function‘);
  }
});

MyClass的直接父类是Ext.Base,因为我们并没有扩展其他。

类的继承层次中,根始终是Ext.Base,也就是说每个类始终都是继承自Ext.Base.所以每个类是Ext.Base的子类,是Ext.Class的实例。这就意味着在之后很容易修改类,比如混合附加功能

//可以在定义类的时候就增加混合功能
Ext.define(‘MyClass‘, {
    mixins: {
        observable: ‘Ext.util.Observable‘
    }
});
//也可以在类定义之后增加
MyClass.mixin(‘draggable‘, ‘Ext.util.Draggable‘);

这种架构开辟了都动态创建类和元编程的新的可能性,这在早期版本是非常困难得。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。