webix源码阅读
2016-07-03 22:34
239 查看
最近在用webix,需要一个类似九宫格的监控界面。自带的控件里没有,于是萌生出做一个Custom Component的需求。不过webix关于自定义控件的文档比较少,官方只有一篇《Creating a Custom Component》讲基本的构建过程,但内容比较浅,和《DIY - Custom Integration Patter》讲的是怎么与第三方组件集成。
对着文档看了几遍,还是觉得没有思路,少不得要去看源码了。里面大把的控件,不都是最好的例子吗。这篇大致讲一下对源码粗浅的理解,下篇展示一个初步成型的九宫格控件。
以button为例,webix对象的构建分为3步:
延迟编译button类:
用config生成button对象:包括调用所有基类的构造函数$init、解析设置_parseSettings、以及调用$ready里的函数链。这个过程会生成button对象和dom树(html+css)。
把对象绘制到dom树中:包括_appendDom、计算Size、以及render。
涉及到的关键步骤如下:
以下几点值得注意:
编译的过程实际上是把其他几个类的属性都合并到1个新的类里,并设置所有Default值,生成prototype,这就是所谓的多继承。
然后把所有类的$init()串在一起,形成新类的$init()。
新类的构造函数里,将依次调用$init、_parseSettings、$ready里的所有方法。
编译的过程只走一次,下次构造button时不会再走。多数类型都是延迟编译,只有必定会用到的基类会在注册后就立马编译,比如:layout、view。这是2个最重要的基类,所以即时编译。
baseView<-view<-(button、window等)朝着各种单独的控件延伸下去
baseView<-baseLayout<-layout<-(toolbar、tabView等)朝着各种布局类延伸下去
2个最重要的基类就是view和layout,其中控件类以render()和on_click等事件处理为核心,布局类以_parse_cells和操作_collection为核心
对"||"的大量运用,用于
注意函数调用过程中this指向的变化、以及Scope上下文的变化(包括Local、Closure和Global)。
闭包一般用于返回待执行的callback,而Type.prototype.func.apply(target, arguments)则可以将target传给任意类的func进行调用。
定义匿名函数并立即执行:
这是我第一个学习的js库,仍有大量值得学习的东西待发掘,新的发现会不断补充进来。
对着文档看了几遍,还是觉得没有思路,少不得要去看源码了。里面大把的控件,不都是最好的例子吗。这篇大致讲一下对源码粗浅的理解,下篇展示一个初步成型的九宫格控件。
1. webix对象的构建过程
我们知道,一句简单的webix.ui({ view: "button" });就能构造1个按钮,背后发生了什么?
以button为例,webix对象的构建分为3步:
延迟编译button类:
webix.protoUI({ name:"button",... });只是一个注册,只有在真正构造之前,才会编译+生成这个类。
用config生成button对象:包括调用所有基类的构造函数$init、解析设置_parseSettings、以及调用$ready里的函数链。这个过程会生成button对象和dom树(html+css)。
把对象绘制到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个新的类里,并设置所有Default值,生成prototype,这就是所谓的多继承。
然后把所有类的$init()串在一起,形成新类的$init()。
新类的构造函数里,将依次调用$init、_parseSettings、$ready里的所有方法。
编译的过程只走一次,下次构造button时不会再走。多数类型都是延迟编译,只有必定会用到的基类会在注册后就立马编译,比如:layout、view。这是2个最重要的基类,所以即时编译。
2. 继承体系
有2条主线:baseView<-view<-(button、window等)朝着各种单独的控件延伸下去
baseView<-baseLayout<-layout<-(toolbar、tabView等)朝着各种布局类延伸下去
2个最重要的基类就是view和layout,其中控件类以render()和on_click等事件处理为核心,布局类以_parse_cells和操作_collection为核心
3. 事件系统EventSystem
待填坑4. js的小技巧
里面有不少js的小技巧值得学习:对"||"的大量运用,用于
undefined || null || 0 || default值的场景,因为js是动态语言,每个逻辑严密的func里都要用类似的方式保证参数有值。
注意函数调用过程中this指向的变化、以及Scope上下文的变化(包括Local、Closure和Global)。
闭包一般用于返回待执行的callback,而Type.prototype.func.apply(target, arguments)则可以将target传给任意类的func进行调用。
定义匿名函数并立即执行:
+function($){...}(jQuery);,常规的写法是:
(function($){...})(jQuery);
这是我第一个学习的js库,仍有大量值得学习的东西待发掘,新的发现会不断补充进来。
相关文章推荐
- 《抗癌前线:癌症研究的前沿进展》:肿瘤基因组学博士的肿瘤科普,三星推荐
- Xcode软件软件中的一些常见单词翻译
- POJ 1995 快速幂
- 获取本机通讯薄的内容
- eclipse/myeclipse空间报错解决方法
- LeetCode-Add Binary
- Python Web 5 —— 错误捕获和错误页
- POJ 1995 快速幂
- android 视频录制 混淆打包 之native层 异常的解决
- 专题四 第十道题
- android 视频录制 混淆打包 之native层 异常的解决
- VC中dll的lib文件和dll有什么不同?
- VC中创建不可改变大小的窗口,及其限制窗口大小的办法
- 【ASP.NET】——有缘千里来相会
- Android跨进程通信
- Spring中提供的util CollectionUtils
- mac 下安装pip
- VC中枚举所有的任务,任务管理器的一些资料的整理
- shell学习笔记
- python开发之路Day17-算法设计(冒泡排序、选择排序、插入排序、二叉树)