YUI3组件框架之plugin
plugin相关源码分析:
plugin功能包括如下几个模块, 简单分析如下:
pluginhost-base
维护对象 this._plugins = {};
并提供方法: plug、unplug、hasplug、_destroyPlugins、_initPlugins
plug: 初始化插件实例,并与host进行关联
if (Plugin && !L.isFunction(Plugin)) {
config = Plugin.cfg;
Plugin = Plugin.fn;
} // Plugin should be fn by now
if (Plugin && Plugin.NS) {
ns = Plugin.NS; config = config || {};
config.host = this; if (this.hasPlugin(ns)) {
// Update config
if (this[ns].setAttrs) {
this[ns].setAttrs(config);
}
} else {
// Create new instance
this[ns] = new Plugin(config);
this._plugins[ns] = Plugin;
}
}
_initPlugins: 调用模块 pluginhost-config 中的_initConfigPlugins(config);
- 根据this._classes(原型链上的constructor对象)上的静态属性 _PLUG and _UNPLUG, 来初始化plugin
- 通过widget初始化时的config配置, 来初始化plugin
- 在YUI Widget体系中base-core模块用来初始化插件, 初始化所有ext和ATTRS后调用
PluginHost.prototype.\_initConfigPlugins = function(config) { // Class Configuration
var classes = (this._getClasses) ? this._getClasses() : [this.constructor],
plug = [],
unplug = {},
constructor, i, classPlug, classUnplug, pluginClassName;
// TODO: Room for optimization. Can we apply statically/unplug in same pass?
for (i = classes.length - 1; i >= 0; i--) {
constructor = classes[i]; classUnplug = constructor._UNPLUG;
if (classUnplug) {
// subclasses over-write
Y.mix(unplug, classUnplug, true);
} classPlug = constructor._PLUG;
if (classPlug) {
// subclasses over-write
Y.mix(plug, classPlug, true);
}
} for (pluginClassName in plug) {
if (plug.hasOwnProperty(pluginClassName)) {
if (!unplug[pluginClassName]) {
this.plug(plug[pluginClassName]);
}
}
} // User Configuration
if (config && config.plugins) {
this.plug(config.plugins);
}
};
pluginhost-config
- _initConfigPlugins
- 静态方法: plug、unplug
- 提供给Y.Base引用
base-pluginhost
mixin Base and PluginHost, 即: Y.mix(Base, PluginHost, false, null, 1);
Base.plug = PluginHost.plug;
Base.unplug = PluginHost.unplug;
plugin
继承Y.Base . 提供AOP的一系列方法, 如:
doBefore: function(strMethod, fn, context) {
var host = this.get("host"), handle;
if (strMethod in host) { // method
handle = this.beforeHostMethod(strMethod, fn, context);
} else if (host.on) { // event
handle = this.onHostEvent(strMethod, fn, context);
}
return handle;
},
doAfter: function() {
...
},
onHostEvent: function() {
var handle = this.get("host").on(type, fn, context || this);
this._handles.push(handle);
return handle;
},
afterHostEvent: function() {
...
},
beforeHostMethod: function() {
...
},
afterHostMethod: function() {
...
}
如何写一个插件
1、 任何简单对象即可成为一个简单插件, 如:
function NodeDrag(config) {
var host = config.host;
drag(host);
}
function drag(host) {
...
}
2、YUI的Plugin基类提供了基于事件的AOP机制支持,可以通过继承它在不影响原有代码逻辑前提下,通过对代码执行过程的控制,达到改变原有代码逻辑或者增加插件功能的效果, 如:
function NodeDrag() {
NodeDrag.superclass.constructor.apply(this, arguments);
}
Y.extend(NodeDrag, Y.Plugin.Base, {
drag: function() {
...
}
});
使用插件的几种方式
给一个node节点添加一个插件
1、使用Base的静态方法, 实际调用的是pluginhost-config里面的plug方法
Y.Base.plug(Y.one('#foo'), NodeDrag, config);
2、node对象和继承了Y.Base对象的实例都可以通过实例直接调用plug方法使用插件
Y.one('#foo').plug(NodeDrag, config);
3、具体widget
function Widget() {}
Y.extend(Widget, Y.Base, {
initializer: function() {
...
}
});
var w = new Widget({plugins: NodeDrag});
//var w = new Widget({plugins: [NodeDrag, ..]});
//var w = new Widget({plugins: {fn: NodeDrag, cfg: {} });
//w.plug(NodeDrag, cfg);
在一些情况,为了让调用者不必过多的关心实现细节的时候,也将插件的初始化放到具体widget的实现中, 如:
Widget.ATTRS = {
drag: {
value: false
}
};
Y.extend(Widget, Y.Base, {
initializer: function() {
if(this.get('drag')) {
this.plug(NodeDrag, cfg);
}
}
});
插件的一些优势和适合的场景
- 插件一般是基于host开发的扩展功能, 用以对host功能的增强,如一些动画效果、也类如dota游戏中一些英雄所具有的各种技能等
- 插件机制能对复杂功能进行更好的抽象, 减少代码逻辑的耦合
- 如,在代码中由于加入一个功能,会涉及到很多代码片段加入if else 判断逻辑, 那么可以考虑将这个功能作为一个plugin增强, 使用AOP的方式与原来代码逻辑关联起来
- 通过host进行统一的入口管理
YUI3组件框架之plugin的更多相关文章
- LCLFramework框架之Plugin模式
插件应用架构概述 基于LCLFramework插件框架的应用由以下三个部分构成: (1)主程序:针对特定应用环境(Web.WinForm等应用环境),加载启动插件,获取插件入口,运行入口程序. (2) ...
- 利用 Dijit 组件框架打造丰富的用户界面
原文出处:Joe Lennon 从头开始学习 Dojo,第 3 部分 利用 Dijit 组件框架打造丰富的用户界面 Dijit 是什么? Dijit 是 Dojo 工具包的富组件用户界面库.这些组件完 ...
- VUE- iView组件框架的使用
VUE- iView组件框架的使用 1. 下载iView 工程. 引用:https://www.iviewui.com/
- 【原】从一个bug浅谈YUI3组件的资源加载
篇前声明:为了不涉及业务细节,篇内信息统一以某游戏,某功能代替 前不久,某游戏准备内测客户端,开发人员测试过程中发现某功能突然不灵了,之前的测试一切ok,没有发现任何异常,第一反应是,游戏内浏览器都是 ...
- 腾讯发布新版前端组件框架 Omi,全面拥抱 Web Components
Omi - 合一 下一代 Web 框架,去万物糟粕,合精华为一 → https://github.com/Tencent/omi 特性 4KB 的代码尺寸,比小更小 顺势而为,顺从浏览器的发展和 AP ...
- Yii2 Template 组件框架集封装
项目简介: Yii2_Template是一个“提供大多数PHP常用的组件去集合成的一套基于Yii2的项目框架”. 该项目是一款秉着提高 开发效率.降低开发成本,遵循高拓展,高可用的原则的进行开发的框架 ...
- stenciljs ionic 团队开发的方便web 组件框架
stenciljs 是ionic 团队开发的方便组件话开发的js 框架,具体以下特点 简单,零配置,简单的api,typescript 支持 性能,压缩之后6Kb,支持ssr,以及强大的原生web c ...
- Vue的iview组件框架select远程搜索,选中后不刷新的问题
1.场景:弹框内有一个下拉组件(支持搜索),当选择完数据后弹框关闭,再次打开后,下拉框内的数据是刚才选中的数据.原因:分析后觉得是搜索内容没有清空,导致下拉的数据只有一个 2.解决方案 a .解决:调 ...
- React 组件框架
随机推荐
- 【读书笔记】《Effective Java》——目录
第二章——创建和销毁对象 第1条:考虑用静态工厂方法替代构造器 第2条:遇到多个构造器参数时要考虑用构建器 第3条:用私有构造器或者枚举类型强化Singleton属性 第4条:通过私有构造器强化不可实 ...
- 7、树莓派编程;gpio编程;led闪烁
本博文仅作本人操作过程的记录,留作备忘.自强不息 QQ12226981 1.树莓派接口对照,一定要找到对应的引脚,不要接错了.我画上箭头. 2.安装 下载地址,https://git.drogon.n ...
- jQuery基础 (四)——使用jquery-cookie 实现点赞功能
jquery-cookie 下载地址:https://github.com/carhartl/jquery-cookie 直接上代码 html <span class="jieda-z ...
- WebRTC 入门到放弃(一)WebRTC
前言 WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Gl ...
- 自己封装的一个js方法用于获取显示的星期和日期时间
自己封装的一个js方法用于获取显示的星期和日期时间 /** * 获取用于显示的星期和日期时间 * @param date * @returns {string} */ function getWeek ...
- Hibernate学习笔记(1)---hibernate快速上手与准备工作
持久层介绍 持久化:将内存中的数据保存在磁盘等存储设备中. 持久化对象:指已经存储在数据库护着磁盘的业务对象 经典的软件应用体系结构(三层结构) 在三层结构中,由于业务逻辑除了负责业务逻辑以外,还要负 ...
- Qt 5中信号和槽的新语法
QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT ...
- Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)
迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...
- 【ASP.NET 系列】浅谈缓存技术在ASP.NET中的运用
本篇文章虽不谈架构,但是Cache又是架构中不可或缺的部分,因此,在讲解Cache的同时,将会提及到部分架构知识,关于架构部分,读者可以不用理解,或者直接跳过涉及架构部分的内容 你只需关心Cache即 ...
- ajax中url赋json格式的值时发生中文乱码的相关问题
具体流程:转入到jsp界面时会加载ajax,ajax转到url时传带hide在jsp界面的值titleString,其来源见下面的代码. String title=new String("\ ...