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 组件框架
随机推荐
- js跳转页面的几种方式
第一种: window.location.href="http://www.baidu.com"; 第二种: window.history.back(-1); 第三种: windo ...
- 点击按钮显示隐藏DIV,点击DIV外面隐藏DIV
点击按钮显示隐藏DIV,点击DIV外面隐藏DIV 注意:此方法对touch事件不行,因为stopPropagation并不能阻止touchend的冒泡 <style type="tex ...
- Django--admin源码流程
admin.py from django.contrib import admin from . import models """ 通过原生的django admi ...
- Java笔记:字符串详解
字符串详解 更新时间:2018-1-6 21:20:39 String 字符串创建 String str1="ABC";//推荐使用 String str2 = new Strin ...
- sed中引用变量
sed 中引用变量 eval sed 's/string/$REPLACE/g' file awk 中引用变量 awk 在匹配字符串的时候,有时候需要需要引用变量. $pid= eval " ...
- SpringMVC 如何在页面中获取到ModelAndView绑定的值
springMVC中通过ModelAndView进行后台与页面的数据交互,那么如何在页面中获取ModelAndView绑定的值呢? 1.在JSP中通过EL表达式进行获取(比较常用) 后台:ModelA ...
- socket对象放在一个datagridview的row的tag里面在拿出来 为什么是已释放
socket对象放在一个datagridview的row的tag里面在拿出来 为什么是已释放
- 浅谈Vue模板的那些事儿
接触过vue的童鞋都知道,组件的模板一般都是在template选项内定义的,如 Vue.component('child-component', { template: '<h3>我是闰土 ...
- AFN中请求序列化的设置
最近遇到一个需求:要求从客户端传到服务器的参数是json字符串,于是我本能的用pod装了afn然后进行了request和response Serialization的相关设置 AFHTTPSessio ...
- php 抽象类和接口类
PHP中抽象类和接口类都是特殊类,通常配合面向对象的多态性一起使用. 相同: ①两者都是抽象类,都不能实例化. ②只有接口类的实现类和抽象类的子类实现了 已经声明的 抽象方法才能被实例化. 不同: ① ...