插件体系

Omi是Web组件化框架,怎么又来了个插件的概念?

可以这么理解: Omi插件体系可以赋予dom元素一些能力,并且可以和组件的实例产生关联。

omi-drag

且看这个例子:

点击这里→在线试试

import OmiDrag from './omi-drag.js';

OmiDrag.init();

class App extends Omi.Component {
constructor(data) {
super(data);
} render() {
return `
<div>
<div omi-drag class="test">Drag Me</div>
</div>
`; } style(){
return `
<style>
.test{
width:100px;
height:100px;
color:white;
line-height:90px;
text-align:center;
background-color:#00BFF3;
}
</style>
`
}
} Omi.render(new App(),"#container");

如上面的代码所示,通过在div上标记omi-drag,这个div就能够被用户使用鼠标拖拽。我们称omi-drag.js为omi插件。

是不是非常方便?那么这个omi-drag是怎么实现的?

Omi.extendPlugin

核心方法: Omi.extendPlugin( pluginName, handler )

下面的代码就是展示了如何通过 Omi.extendPlugin 赋予dom拖拽的能力:

;(function () {

    var OmiDrag = {};
var Omi = typeof require === 'function'
? require('omi')
: window.Omi; OmiDrag.init = function(){
Omi.extendPlugin('omi-drag',function(dom, instance){
dom.style.cursor='move';
var isMouseDown = false,
preX = null,
preY = null,
currentX = null,
currentY = null,
translateX = 0,
translateY = 0; dom.addEventListener('mousedown',function(evt){
isMouseDown = true;
preX = evt.pageX;
preY = evt.pageY;
evt.stopPropagation();
},false); window.addEventListener('mousemove',function(evt){
if(isMouseDown){
currentX = evt.pageX;
currentY = evt.pageY;
if(preX != null){
translateX += currentX - preX;
translateY += currentY - preY;
dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)';
}
preX = currentX;
preY = currentY;
evt.preventDefault();
}
},false); window.addEventListener('mouseup',function(){
isMouseDown = false;
preX = preY = currentX = currentY = null;
},false);
});
} OmiDrag.destroy = function(){
delete Omi.plugins['omi-drag'];
}; if (typeof exports == "object") {
module.exports = OmiDrag;
} else if (typeof define == "function" && define.amd) {
define([], function(){ return OmiDrag });
} else {
window.OmiDrag = OmiDrag;
} })();

方法: Omi.extendPlugin( pluginName, handler )

其中pluginName为插件的名称

其中handler为处理器。handler可以拿到标记了pluginName的dom以及dom所在的组件的实例,即 dom 和 instance。

通过 Omi.extendPlugin,可以赋予dom元素一些能力,也可以和组件的实例(instance)产生关联。

但是上面的例子没有和instance产生关联,我们接下来试试:

关联instance

我们想在组件里面能够监听到move并且执行回调。如下:

...
...
moveHandler(){
console.log('moving');
} render() {
return `
<div>
<div omi-drag class="test">Drag Me</div>
</div>
`;
}
...

主要被拖动过程中,moveHandler就不断地被执行。插件代码需要修改:

...
window.addEventListener('mousemove',function(evt){
if(isMouseDown){
currentX = evt.pageX;
currentY = evt.pageY;
if(preX != null){
translateX += currentX - preX;
translateY += currentY - preY;
dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)';
}
preX = currentX;
preY = currentY;
evt.preventDefault();
instance.moveHandler(evt);
}
},false);

我们在里面增加了instance.moveHandler(evt);方法,用来执行组件实例上的moveHandler方法。

这样的话:就是组件的实例(instance)产生关联。但是还是有问题?如果标记了多个omi-drag 就会有问题!如:

...
render() {
return `
<div>
<div omi-drag class="test">Drag Me</div>
<div omi-drag class="test">Drag Me</div>
</div>
`;
}
...

通常我们系统每个omi-drag都能对应一个回调函数,如:

...
...
moveHandlerA(){
console.log('moving');
} moveHandlerB(){
console.log('moving');
} render() {
return `
<div>
<div omi-drag class="test">Drag Me A</div>
<div omi-drag class="test">Drag Me B</div>
</div>
`;
}
...

怎么办?怎么实现?有办法!通过dom传递数据给插件。

传递数据

先来看最后实现的效果:

...
...
moveHandlerA(){
console.log('moving');
} moveHandlerB(){
console.log('moving');
} render() {
return `
<div>
<div omi-drag class="test" dragMove="moveHandlerA" >Drag Me A</div>
<div omi-drag class="test" dragMove="moveHandlerB" >Drag Me B</div>
</div>
`;
}
...

omi-drag修改的地方:

...
var handlerName = dom.getAttribute('dragMove'); window.addEventListener('mousemove',function(evt){
if(isMouseDown){
currentX = evt.pageX;
currentY = evt.pageY;
if(preX != null){
translateX += currentX - preX;
translateY += currentY - preY;
dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)';
}
preX = currentX;
preY = currentY;
evt.preventDefault();
instance[handlerName](evt);
}
},false);
...
  • 通过 var handlerName = dom.getAttribute('dragMove') 拿到dom上声明的dragMove
  • 通过 instancehandlerName 去执行对应的方法

点击这里→在线试试

更多插件

相关

  • Omi的Github地址https://github.com/AlloyTeam/omi
  • 如果想体验一下Omi框架,可以访问 Omi Playground
  • 如果想使用Omi框架或者开发完善Omi框架,可以访问 Omi使用文档
  • 如果你想获得更佳的阅读体验,可以访问 Docs Website
  • 如果你懒得搭建项目脚手架,可以试试 omi-cli
  • 如果你有Omi相关的问题可以 New issue
  • 如果想更加方便的交流关于Omi的一切可以加入QQ的Omi交流群(256426170)

Omi教程-插件体系的更多相关文章

  1. Geronimo tomcat: 在 Apache Geronimo 插件体系中将 Apache Tomcat 这个优秀的 Web 容器整合至其中

    Apache Geronimo 灵活的插件体系将 Tomcat, OpenJPA, OpenEJB, ActiveMQ 等第三方组件集成至其中.本文从多角度介绍了在 Apache Geronimo 中 ...

  2. Omi教程-组件

    组件 Omi框架完全基于组件体系设计,我们希望开发者可以像搭积木一样制作Web程序,一切皆是组件,组件也可以嵌套子组件形成新的组件,新的组件又可以当作子组件嵌套至任意组件形成新的组件... 简单组件 ...

  3. Omi框架Store体系的前世今生

    原文链接-https://github.com/AlloyTeam/omi Store 体系 先说说Store系统是干什么的!为什么要造这样一个东西?能够系统架构带来什么? 当我们组件之间,拥有共享的 ...

  4. ABP入门教程2 - 体系架构

    点这里进入ABP入门教程目录 介绍 应用程序代码库的分层是一种广泛接受的技术,可帮助降低复杂性并提高代码可重用性.为了实现分层体系结构,ASP.NET Boilerplate遵循域驱动设计的原理. D ...

  5. atitit.插件体系设计总结o73.doc

    1. 两大类型:微内核(级联树形结构)与巨内核(管理容器,并联结构). 1 2. 通用插件接口 1 3. 插件的绑定and 初始化 2 4. 微内核插件平台设计 2 5. 参考 2 1. 两大类型:微 ...

  6. Omi教程-组件通讯

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 父容器设置 childrenData ...

  7. Omi教程-使用group-data通讯

    写在前面 Omi框架组建间的通讯非常遍历灵活,上篇文章介绍了几种通讯方式,其中childrenData的方式可以批量传递数据给组件,但是有很多场景下data的来源不一定非要都从childrenData ...

  8. Omi教程-通讯通讯攻略大全

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射) 父容器设 ...

  9. Omi教程-生命周期和事件处理

    生命周期 名称 含义 时机 constructor 构造函数 new的时候 install 初始化安装,这可以拿到用户传进的data进行处理 实例化 installed 安装完成,HTML已经插入页面 ...

随机推荐

  1. JMeter 连接数据库报错No suitable driver found for jdbc:xxxxxxxxx

    添加JDBC Connection Configuration 和 JDBC Request 组件,添加相关信息 注意两个组件里面输入的Variable Name 必须一致 运行查看结果树出现如下错误 ...

  2. ubuntu16.04 安装搜狗输入法

    刚刚升级ubuntu16.04LTS,安装搜狗输入法又出问题. 和以前一样,在官网下了deb包,直接双击安装,打开了Software Center(如下:改版过了,但是看起来是没有安装上的),点Ins ...

  3. iOS 错误 之 Unexpected interface name 'HomeListCell': expected expression

    说明:不应该是类HomeListCell:应该是表达式. 出现场景:赋值时,等号右面是个类名,而不是变量名.

  4. 一个参数引起的mysql从库宕机血案

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://suifu.blog.51cto.com/9167728/1859252 一个参数 ...

  5. delphi popupmenu控件用法

    是,右键菜单控件,和特定的窗体控件的popmenu属性关联就可以了 添加一个popupmenu控件,双击该控件,在弹出的界面中设置好name以及caption属性,点击事件的做法就跟button一样了 ...

  6. cygwin下配置alias

    主要是cygwin下的盘符映射关系容易忘,直接用mount命令: 所以,找到E:\cygwin64\home\Administrator下面的.bashrc,添加alias.如下:

  7. JAVA中Singleton的用法

    Java Singleton模式属于管理实例化过程的设计模式家族.Singleton是一个无法实例化的对象.这种设计模式暗示,在任何时候,只能由JVM创建一个Singleton(对象)实例. JAVA ...

  8. quick-cocos2d-x添加到Pomelo的支持

    https://github.com/luoxinliang/pomelo_quick_x/tree/master/pomelo_quick_x

  9. easyui message show中msg嵌入一个按钮如何绑定事件

    http://www.oschina.net/question/945028_171927

  10. Canvas globalCompositeOperation API

    参考: http://www.cnblogs.com/jenry/archive/2012/02/11/2347012.html <!DOCTYPE html> <html lang ...