最近在用webix,需要一个类似九宫格的监控界面。自带的控件里没有,于是萌生出做一个Custom Component的需求。不过webix关于自定义控件的文档比较少,官方只有一篇《Creating a Custom Component》讲基本的构建过程,但内容比较浅,和《DIY - Custom Integration Patter》讲的是怎么与第三方组件集成。

对着文档看了几遍,还是觉得没有思路,少不得要去看源码了。里面大把的控件,不都是最好的例子吗。这篇大致讲一下对源码粗浅的理解,下篇展示一个初步成型的九宫格控件。

1. webix对象的构建过程

我们知道,一句简单的webix.ui({ view: "button" });就能构造1个按钮,背后发生了什么?

以button为例,webix对象的构建分为3步:

  1. 延迟编译button类:webix.protoUI({ name:"button",... });只是一个注册,只有在真正构造之前,才会编译+生成这个类。
  2. 用config生成button对象:包括调用所有基类的构造函数$init、解析设置_parseSettings、以及调用$ready里的函数链。这个过程会生成button对象和dom树(html+css)。
  3. 把对象绘制到dom树中:包括_appendDom、计算Size、以及render。

涉及到的关键步骤如下:

ui = webix.ui = function(config, parent, id){
top_node = ui._view(config);
_appendDom(node, top_node, config);
}; //注册button类,返回button类的编译函数t
webix.protoUI = function(){
var t = function(data){
webix.ui[selfname] = webix.proto.apply(webix, params);
};
}; //真正编译生成原型(button类)的地方,包括:
//1. 多继承(将所有基类属性+func拼到1个button类里)
//2. 将所有基类构造函数$init拼成1个自己的大的构造函数等
webix.proto = function(){
for(var key in origins[i]){
compilation[key] = origin[i][key];
}
compilation.$init = function(){
for(var i=0;i<construct.length;i++)
construct[i].apply(this, arguments);
};
var result = function(config){};
result.prototype = compilation;
return result;
}; var _appendDom = function(node, top_node, config){
node.appendChild(top_node._viewobj);
top_node.adjust(); // $setSize()->render()
};

以下几点值得注意:

  1. 编译的过程实际上是把其他几个类的属性都合并到1个新的类里,并设置所有Default值,生成prototype,这就是所谓的多继承。
  2. 然后把所有类的$init()串在一起,形成新类的$init()。
  3. 新类的构造函数里,将依次调用$init、_parseSettings、$ready里的所有方法。
  4. 编译的过程只走一次,下次构造button时不会再走。多数类型都是延迟编译,只有必定会用到的基类会在注册后就立马编译,比如:layout、view。这是2个最重要的基类,所以即时编译。

2. 继承体系

有2条主线:

  1. baseView<-view<-(button、window等)朝着各种单独的控件延伸下去
  2. baseView<-baseLayout<-layout<-(toolbar、tabView等)朝着各种布局类延伸下去

2个最重要的基类就是view和layout,其中控件类以render()和on_click等事件处理为核心,布局类以_parse_cells和操作_collection为核心

3. 事件系统EventSystem

待填坑

4. js的小技巧

里面有不少js的小技巧值得学习:

  1. 对"||"的大量运用,用于undefined || null || 0 || default值的场景,因为js是动态语言,每个逻辑严密的func里都要用类似的方式保证参数有值。
  2. 注意函数调用过程中this指向的变化、以及Scope上下文的变化(包括Local、Closure和Global)。
  3. 闭包一般用于返回待执行的callback,而Type.prototype.func.apply(target, arguments)则可以将target传给任意类的func进行调用。
  4. 定义匿名函数并立即执行:+function($){...}(jQuery);,常规的写法是:(function($){...})(jQuery);

这是我第一个学习的js库,仍有大量值得学习的东西待发掘,新的发现会不断补充进来。

webix源码阅读的更多相关文章

  1. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  2. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  3. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  4. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  5. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  6. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  7. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  8. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  9. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. 分列:将excel单元格的内容拆分为两列

    提要:处理excel数据时有时需要把单元格的内容拆分为两列,可能方便外部软件的链接,可能使数据显示更明晰等等,有人说直接剪切加粘贴不就可以了吗,但是有时数据过多,这样处理很不效率,网上搜索的方法说插入 ...

  2. 本地json文件的编辑器,node-webkit开发的exe程序

    首发:个人博客,更新&纠错&回复 在昨天的dota契合度计算器中,用到了dota英雄数据和dota玩家数据这两个数据库,为了便于网页应用使用,这两个数据库的存储格式是json,即her ...

  3. imail 删除历史邮件命令

    删除旧的邮件(immsgexp.exe)Immsgexp.exe 可以让管理员删除指定天数的旧的邮件.基本语法 immsgexp -t startdirectory -d #of_days_to_sa ...

  4. 使用C# yield关键字来提高性能和可读性

    对于”yield”这个关键字我已经见过N次了,直到最近我才知道这个关键字所蕴含的力量.我将在下面展示出一些使用”yield”让你的代码有更高可读性和更好性能的例子. 为了让你对yield有一些快速概览 ...

  5. Posix消息队列

    转载于:http://blog.csdn.net/zx714311728/article/details/53197196 1.消息队列 消息队列可以认为是一个消息链表,消息队列是随内核持续的.队列中 ...

  6. asp.net服务控件的生命周期

    1. 初始化 - Init事件 (OnInit 方法)   2. 加载视图状态 - LoadViewState方法   3. 处理回发数据 - LoadPostData方法           对实现 ...

  7. Web_add_header

    如果你发现所有的HTTP send请求都缺少头数据包,在脚本中的开头添加web_add_auto_header(”XXXXX“,”yyyy“);随着web_add_auto_header的添加,你不需 ...

  8. 如何做个简单安卓App流程

    有同学做毕业设计,问怎样做个简单安卓App流程,我是做服务端的,也算是经常接触app,想着做app应该很简单吧,不就做个页面,会跳转,有数据不就行了,我解释了半天,人家始终没听懂,算了,我第二天问了下 ...

  9. U3D使anim,unity,prefab文件不显示乱码

    Edit-Project Setting-Editor-Asset Serialization-mode Force Text

  10. 【转】ini载入保存类,操作INI配置文件方便的很

    /****************************************************************** * * ^_^ 恶猫 独门商标 挖哈哈 * * QQ:\> ...