zoukankan      html  css  js  c++  java
  • ExtJS4 源码解析(一)带项目分析

         Ext这个东东太大了,能看完就已经很不错了,完整的源码分析就不敢说了,大概就涉及了类管理,事件管理,数据结构缓存架构,UI组件核心机制,MVC这几个方面,只是挑着源码看的,没有实际完整的使用.

    公司的框架我是借鉴了EXT的结构..站在巨人的肩上我们可以走的更远,内部的结构我已经改动了,组件的形式去架构不适合咱公司~

         如图~

         image

     

    • 昨天遇到个问题在mixins(向创建的类中要掺进其它类的信息)多个的时候就出问题了~ 顺便就发一下我的源码分析吧.当然是个人角度,有错误欢迎指出.
    • 发几本EXT的书,以前分析代码的时候看过了,感觉还行

    image

     

    EXT3.4 到 4.0改动真心很大…以前是用3.4玩的,后来看到4.0又把代码给整个重构了一次

     

    这里先着重讲一下 ExtJs4.0 Class的实现:

    ExtJs4.0中,涉及Class实现的主要是Ext Core , Ext.Class, Ext.Base, Ext.ClassManager 这几个对象

    • Base.js定义了Base类,Base类是ExtJS4.0中所有通过Ext.define定义的类的直接或间接父类,Base类中定义了一些通用的实例与静态属性与方法;
    • Class.js文件中定义了Class类,所有通过Ext.define定义的类都是Class的实例(其实是Class构造函数中的newClass类);
    • ClassManager.js文件中定义了ClassManager单例,它主要负责对类的管理,如类的创建与类实例化等;
    • Loader文件中定义了Loader单例,实现了ExtJS4.0中动态加载类的功能。

    image

    我是用的sencha分析的,不过sencha也是基于ext的


    在ExtJs4.0中,声明类的方式改为了 Ext.define('ClassName',{}); 这个方法其实是Ext.ClassManager.create的一个别名,具体用法请看API吧,这里只谈谈具体的实现

    分析代码咱先从入口开始

    Ext.define 在Ext.ClassManager中

    
    
       1:          /**
       2:           * Convenient shorthand for {@link Ext.ClassManager#create}, see detailed {@link Ext.Class explanation}
       3:           * @member Ext
       4:           * @method define
       5:           *    alert( Object.keys(Ext.ClassManager.classes) )
       6:           */
       7:          define: alias(Manager, 'create'),
    
    
    alias(object, methodName):顾名思义,别名方法,将object的mothodName方法赋予给指定对象

    实际上的处理函数就是定义在 Manager上的create方法了

    在这个过程中,首先通过 Ext.Class建立原始Class,填充应用Ext.define中的配置信息,类预处理器。

       1:   return new Class(data, function() {
       2:   
       3:                  var postprocessors = Ext.Array.from(data.postprocessors || manager.getDefaultPostprocessors()),
       4:                      process = function(clsName, cls, clsData) {
       5:                          var name = postprocessors.shift();
       6:   
       7:                          if (!name) {
       8:                              manager.set(className, cls);
       9:   
      10:                              if (Ext.isFunction(createdFn)) {
      11:                                  createdFn.call(cls, cls);
      12:                              }
      13:   
      14:                              return;
      15:                          }
      16:   
      17:                          this.getPostprocessor(name).call(this, clsName, cls, clsData, process);
      18:                      };
      19:   
      20:                  process.call(manager, className, this, data);
      21:              });

    在此方法内部,会先将className添加到data,之后会new一个Class并返回,所以可以说Ext.define出的类都是Class这个类的实例,这里其实是Class构造函数中的newClass类,Class实例都被Manager.classes给保存着

    由此可见

    ClassManager.js只是定义了ClassManager单例,它主要负责对类的管理,如类的创建与类实例化等;


    真正核心的文件Class.js

       1:    Ext.Class = function(newClass, classData, createdFn) {

    其实内部转换做了几件事:用自己的语言表述下

    1. 定义新类
    2. 拷贝base静态方法到新的类中,就是最终的基类,在EXT3.4中最终顶层是事件Observable
    3. 预处理器(其实就是被一轮预定义的代码给XXXX一遍)
    4. 返回newClass这个新类

    其实在外部还有后处理器,这个以后再说


    具体的实现咱们看源码:

       1:          if (Ext.isObject(newClass)) {
       2:              createdFn = classData;
       3:              classData = newClass;
       4:              newClass = function() {
       5:                  return this.constructor.apply(this, arguments);
       6:              };
       7:          }

    这里要这样写,其实这里涉及到了EXT的组件模型管理机制

    EXT是一套继承体系,

    我先搬运一张3.4的图(4.0也类似)

    image

     

    用我的理解就是一种倒序法,简单的说

    Extjs组件架构采用的是 一套倒树结构,父类子类之间关系是可以通过继承实现

    还是用我的项目为例吧,反正这个东东我也实现了

    new 一个Content对象

       1:   
       2:          //Activity行为预创建节点,支持PPT多动画
       3:          if (sqlRet.imageId) {
       4:              return function(rootEle, pageIndex) {
       5:                  Xut.create('Xut.Content', {
       6:                      'container'   : rootEle || opts.rootEle,
       7:                      "type"        : 'Content',
       8:                      "id"          : sqlRet.imageId,
       9:                      "pageIndex"   : pageIndex,
      10:                      "isAutoPlay"  : false,
      11:                      "activityMode": true, //针对预先触摸加载方式
      12:                      "processstate": "preprocess"
      13:                  })
      14:              }
      15:          }

    如图创建了一个  new Xut.Content 对象, 可是在实际构造中,代码的开始执行确实最顶层基类Xut.Component

    代码中的实现

    定义的Xut.Content 类

    
    

                                  

       1:  Xut.define('Xut.Content', {                
       2:                                             
       3:      //继承Xut.ActionBase类                 
       4:      extend: 'Xut.ActionBase',              
       5:                                             
       6:      //PPT动画接口                          
       7:      mixins: {                              
       8:          EffectApi: 'Xut.EffectApi'         
       9:      },

     

       1:  //================ 热点动作处理类=============
       2:  //
       3:  //  点击动作行热点基类
       4:  //   
       5:  //   继承  Xut.Behavior 行为基类
       6:  //  
       7:  //   1 获取数据
       8:  //   2 配置关闭按钮
       9:  //
      10:  //
      11:  Xut.define('Xut.ActionBase', {
      12:   
      13:      /* 开始定义 */
      14:   
      15:      extend: 'Xut.Behavior',

     

       1:  //================ 热点动作处理类=============
       2:  // 
       3:  //  热点具有的基本行为动作
       4:  //      
       5:  //  1 Iscroll 导入扩展
       6:  //  
       7:  //  2 关闭按钮生成
       8:  //   
       9:  //  3 创建关闭按钮
      10:  //
      11:   
      12:  Xut.define('Xut.Behavior', {
      13:   
      14:      /* 开始定义 */
      15:   
      16:      extend: 'Xut.Component',
    //==============UI交互动作基类===================
    //  
    //  子类  
    //    触发型热点 ActionBase
    //    交互型热点 WidgetBase
    //
    
    Xut.define('Xut.Component', {
    
        /* 开始定义 */
    
        mixins: {
            observable: 'Xut.core.Observable'
        },
    
        statics: {
            AUTO_ID: 1000
        },

     

    执行循序

    new Xut.Content –> Xut.Component –> Xut.Behavior –> Xut.ActionBase –> Xut.Content –>

    开始又往上层找 Xut-ActionBase –>Xut.Behavior->Xut.ActionBase –> Xut.Component

    是不是很晕。。。ext内部就是这样玩的,为什么要这样,以后如果有时间说下UI组件机制就知道了

     

    回归正题,这样的倒序调用,是怎么实现的

    new一个子类,直接跨过N层到了基类Xut.Component

    大家回过神来

       1:  newClass = function() {
       2:           return this.constructor.apply(this, arguments);
       3:    };

    注意这里

    核心点

    return this.constructor.apply(this, arguments);

    当我们传递的第一个参数不是对象(函数也是对象),那么EXT内部帮我构造了个 构造函数

    这是有什么用?第二节接着分析

  • 相关阅读:
    【bzoj4152】[AMPPZ2014]The Captain 堆优化Dijkstra
    【bzoj4547】Hdu5171 小奇的集合 矩阵乘法
    【bzoj1264】[AHOI2006]基因匹配Match 树状数组
    【bzoj3856】Monster 乱搞
    【bzoj4724】[POI2017]Podzielno 二分
    【bzoj4976】宝石镶嵌 乱搞+dp
    【bzoj4070】[Apio2015]雅加达的摩天楼 set+堆优化Dijkstra
    【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组
    【bzoj2124】等差子序列 STL-bitset
    【bzoj1996】[Hnoi2010]chorus 合唱队 区间dp
  • 原文地址:https://www.cnblogs.com/aaronjs/p/3147568.html
Copyright © 2011-2022 走看看