`
dinguangx
  • 浏览: 244753 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

通过标签属性扩展来实现operamasks-ui的组件定义

    博客分类:
  • OMUI
阅读更多

最近在学习OperamasksUI(版本v2.1)的时候,有了一个想法,想把UI的组件生成通过标签属性扩展的方式来实现。比如对于按钮,通过标签扩展,增加left-icon,right-icon,label,width等属性来实现属性的定义,而通过扩展一个fn属性来达到对事件的定义。如:

 

<a class="ui-button" label="按钮3" id="btn3" fn="{onClick:function(){alert('按钮3的事件通过扩展属性fn实现');}}"
		left-icon="${ctx }/static/icons/down.png" width="100"
		right-icon="${ctx }/static/icons/help.png"></a>

     这样的标签扩展带来的好处有:

(1) 页面中不再需要大量的JSONJS代码,减少了维护的工作量

(2) 降低了开发人员学习om-ui的难度

(3) 能够方便地通过属性的是否输出或EL表达式等方式实现权限的控制。

(4) 标签扩展的代码样式可以方便地通过代码生成器来达到快速生成代码的目的。

由于我自己是做java开发的,所以对于这里的(3)和(4),是很容易来实现的。其实我的终极目的就是要通过代码生成器来达到快速开发的目的。现在的java应用中,一般都会通过自定义TAG的方式来实现快速开发,自定义tag可以做更多的事情,将很复杂的功能封装在一个简单的tag里,但是考虑到自定义tag的可扩展性和可维护性,以及跨语言平台的原因,我还是更愿意尝试通过标签扩展的方式来实现这个目标(当然,我也很想与同行交流一下,自定义tag与标签扩展方式的优劣)。

在对方法的调用上,Operamaks-ui基于和jquery-ui同样的思想,比如对于Dialogopen方法,调用代码如下:

$("#dialog").omDialog("open");

 这与我们通常所说的面向对象编程理念不太一致,面向对象的编程思想中,对于一个Dialogopen方法,应该是这样的调用代码:

dialog.open()

 就是说,在组件生成之后,应该把句柄暴露给开发者,开发者直接通过该句柄即可完成对方法的调用。

基于这样的思路,我先是对最基本的两个组件:按钮和对话框进行了封装和改造,具体的代码如下(operamasks-ui-plugin.js)

$.omPlugin={};
$.extend.apply($.omPlugin,{
	"omButtonbar":{},
	"omButton":{},
});
$.omPlugin["omButtonbar"]={
	attrs:["width"]
};
$.omPlugin["omButton"]={
	attrs:["label","width","disabled"],
	methods:["changeIcons","changeLabel","click","disable","enable"]
};
$.omPlugin["omDialog"]={
		attrs:["autoOpen|b","closeOnEscape|b","modal|b","resizable|b","title","width","zIndex","dialogClass","draggable|b","height","maxHeight","maxWidth","minWidth"],
		methods:["close","isOpen","open"]
};
$.omPlugin["omDialog-Button"]={
		attrs:["text"]
};
/**
 * 对页面中的控件以定义的class进行初始化
 * @param $config 预定义的配置信息
 */
function initUI($config) {
	var $$config = $config || {};
	// 清理浏览器内存,只对IE起效
	$(document).ajaxStart(function() {
		//
	}).ajaxStop(function() {
		//
	});
	
	function $generateId($uiType){
		$uiType = $uiType || "Control";
		var idCounter = $(window).data("_ID_COUNTER") || 10000;
		var $ret = $uiType + "_" + idCounter;
		$(window).data("_ID_COUNTER",++idCounter);
		return $ret;
	}
	/**
	 * 从扩展标签中提取属性的定义
	 */
	function $buildConfig($obj,$uiType){
		// 这里的id一定需要
		var $config = {id:$obj.attr("id")};
		if(!$config.id){
			$config.id=$generateId();
		} else {
			if($.isPlainObject($$config[$config.id])){
				$.each($$config[$config.id],function(k,v){
					$config[k]=v;
				});
			}
		}
		$obj.attr("id",$config.id);
		var $arrAttr = null;
		var $arrFn=null;
		//加载扩展属性
		if($uiType && $.omPlugin[$uiType]){
			$arrAttr = $.omPlugin[$uiType].attrs;
			$arrFn = $.omPlugin[$uiType].fn;
		}
		$.isArray($arrAttr) && $.each($arrAttr,function(i,attr){
			var $attrN=attr;
			var $attrT=null;
			if(attr && attr.length >2 && attr.charAt(attr.length-2)=="|"){
				$attrN=attr.substring(0,attr.length-2);
				$attrT=attr.charAt(attr.length-1);
			}
			var $v = $obj.attr($attrN);
			if($v && $attrT==="b"){
				$v = $v==="true" ? true : $v==="false"?false : undefined;
			}
			if(typeof($v) != "undefined"){
				($config[$attrN]=$v);
			}
		});
		//从扩展属性fn中取出事件的配置
		if($obj.attr("fn")){
			var fn = eval("("+$obj.attr("fn")+")");
			$.extend($config,fn);
		}
		return $config;
	}
	/**
	 * 创建UI对象,并将对象ID作为句柄附加给window对象,以快速调用其方法
	 */
	function $buildUI($obj,$uiType,$config){
		
		var $ui = $obj[$uiType]($config);
		var $dom = $obj[0];
		$dom._ui=$dom.$=$ui;
		var $instance = $ui.data($uiType);
		var $arrMethod = null;
		if($uiType && $.omPlugin[$uiType]){
			$arrMethod = $.omPlugin[$uiType].methods;
		}
		$.isArray($arrMethod) && $.each($arrMethod,function(i,method){
			if($instance && $.isFunction( $instance[method] )){
				$dom[method]=function(){
					//暴露公共函数
					return $instance[method].apply($instance,arguments);
				};
			}
		});
	}

	// buttonbar工具栏及button
	if($.fn.omButtonbar && $.fn.omButton){
		/**
		 * 生成按钮的配置信息
		 */
		function $buildButtonConfig($obj) {
			var $config = $buildConfig($obj,"omButton");
			return $.extend($config,{
				label : $config.label || $obj.attr("label") || null,
				icons : {
					left : $obj.attr("left-icon") || null,
					right : $obj.attr("right-icon") || null
				}
			});
		}
		$(".ui-buttonbar").each(function() {
			var $this = $(this);
			var $config = $buildConfig($this,"omButtonbar");
			var $buttons = [];
			$(".ui-button", $this).each(function() {
				$buttons.push($buildButtonConfig($(this)));
			});
			$config.btns=$buttons;
			$buildUI($this,"omButtonbar",$config);
		});
	
		$(".ui-button").each(function() {
			var $this = $(this);
			if(!$this.parent(".ui-buttonbar").length){
				$buildUI($this,"omButton",$buildButtonConfig($this));
			}
	    });
	}
	// dialog
	if($.fn.omDialog){
		$(".ui-dialog").each(function() {
			var $this = $(this);
			var $config = $buildConfig($this,"omDialog");
			var $buttons = [];
			$(".ui-dialog-button", $this).each(function() {
				var $btnConfig = $buildConfig($(this),"omDialog-Button");
				$buttons.push($btnConfig);
			});
			$config.buttons=$buttons;
			$buildUI($this,"omDialog",$config);
		});
	}
}

 这里完成了对Buttonbar Button Dialog三个组件的封装。对于支持的属性扩展,通过$.omPlugin[组件类型].attrs进行预定义;而对于需要暴露的方法,通过$.omPlugin[组件类型].methods进行预定义。

 

先来看一下对于ButtonbarButton的测试代码(这里是用jsp技术来做的,但没有夹杂太多的java代码,其他语言的开发者应该可以很方便地把它改造成HTML代码或asp代码,如果有不明白的地方,欢迎进行交流。)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@include file="/WEB-INF/include/taglibs.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>插件使用示例</title>
<d:script id="jquery,om-ui" />
<d:script path="/static/om-ui/operamasks-ui-plugin.js" />
<d:css id="om-ui" />

<script type="text/javascript">
	function click(){
		alert("通过全局的事件及fn扩展属性实现点击事件.");
	}
	function changeLabel() {
		btn3.changeIcons({
			right : "${ctx}/static/icons/down.png"
		})
	}
	function disable() {
		btn3.disable();
	}
	function enable() {
		btn3.enable();
	}
	$(document).ready(function() {
		initUI({
			"btn4":{
				label:"按钮4(标签通过预定义的配置实现)",
				width:320,
				onClick:function(e){alert("通过initUI的初始化配置实现点击事件.");}
			}
		});
	});
</script>
<style type="text/css">
html,body {
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
}
</style>
</head>
<body>
	<div class="ui-buttonbar">
		<a class="ui-button" label="按钮1"
			left-icon="${ctx }/static/icons/down.png"
			right-icon="${ctx }/static/icons/help.png" fn="{onClick:click}"></a>
		<a class="ui-button" label="按钮2"
			left-icon="${ctx }/static/icons/down.png"
			right-icon="${ctx }/static/icons/help.png" fn="{onClick:click}"></a>
	</div>
	<a class="ui-button" label="按钮3" id="btn3" fn="{onClick:function(){alert('按钮3的事件通过扩展属性fn实现');}}"
		left-icon="${ctx }/static/icons/down.png" width="100"
		right-icon="${ctx }/static/icons/help.png"></a>
		

	<input type="button" value="更改btn3的标签" onclick="changeLabel();">
	<input type="button" value="禁用" onclick="disable();">
	<input type="button" value="启用" onclick="enable();">
	<!--  -->
	<br/>
	<button class="ui-button" id="btn4"
		left-icon="${ctx }/static/icons/down.png"
		right-icon="${ctx }/static/icons/help.png"></button>
</body>
</html>

 可以看到这里的页面中并没有太多的JS代码,都是一些简单的JS函数。对于没有jquery基础,或者json应用不熟练的开发人员,也能很容易看懂。而且对按钮3的启用和禁用使用的代码为:

btn3.enable();
btn3.disable();

 

这里的btn3就是标签中的ID属性。

生成的页面效果如下图,对于事件和方法和调用都通过了测试:



 

再来看一下对于dialog的测试:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@include file="/WEB-INF/include/taglibs.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>插件使用示例</title>
<d:script id="jquery,om-ui" />
<d:script path="/static/om-ui/operamasks-ui-plugin.js" />
<d:css id="om-ui" />

<script type="text/javascript">
	$(document).ready(function() {
		initUI();
	});
</script>
<style type="text/css">
html,body {
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
}

</style>
</head>
<body>
<a class="ui-button" label="打开第二个对话框" fn="{onClick:function(){dialog2.open()}}"></a>
	<div id='dialog1' class="ui-dialog" draggable="false" modal="false" title="第一个对话框" resizable="false">
		<span class="ui-dialog-button" text=" 是否打开 " fn='{click:function(){alert("第一个是否打开:" + dialog1.isOpen());}}'></span>
		<span class="ui-dialog-button" text=" 关闭 " fn='{click:function(){dialog1.close();}}'></span>
		第一个对话框的内容
	</div>
	
	
	<div id='dialog2' class="ui-dialog" autoOpen=false draggable="false" modal="true" title="第二个对话框" resizable="false">
		<span class="ui-dialog-button" text=" 关闭 " fn='{click:function(){dialog2.close();}}'></span>
		第二个对话框的内容(默认是不可见的)
		<a class="ui-button" label="检查是否打开" fn="{onClick:function(){alert('第二个对话框是否打开:' +dialog2.isOpen())}}"></a>
	</div>
</body>
</html>

 页面打开之后的效果如下:



 

点击左上角的【打开第二个对话框】按钮,将会弹出第二个对话框,点击对话框中的【检查是否打开】按钮,会弹出对应的提示信息,如图:



 

 

目前已经实现的只有这两个组件,后续将会不断增加对其他常用组件的实现,希望能与感兴趣的同学一起交流这样的实现方式,也十分期待能有志同道合的朋友能一起进行后续的开发。目前在组件的事件实现方面,是通过扩展了一个fn属性,并在fn属性中传递json格式的事件定义实现的,自己感觉这种方式并不是很好,但是还没更好的方法;也希望各位朋友能提一些宝贵的意见,对事件的处理方面进行一些优化。

  • 大小: 9.3 KB
  • 大小: 17.5 KB
  • 大小: 25.5 KB
分享到:
评论

相关推荐

    operamasks-ui 帮助文档

    只是我在网上找的 operamasks-ui api 文档 , 希望对你们有帮助

    operamasks-ui-2.0

    operamasks-ui-2.0 这个帮助文档很难才找到的,感谢CSDN,其中的说明真的是很详细了,维护旧代码用到的这个框架,相比easyui和bootstrap这个框架简单一些,不过用起来还是不错的,除了文档太少,不过有这个就基本...

    operamasks-ui-2.0-demo.zip

    "Operamasks UI 2.0 Demo"是一个与JavaScript相关的压缩包,包含了对Opera Masks用户...实际使用时,开发者需要按照readme.txt的指示进行操作,并通过operamasks-ui.war文件了解和体验Opera Masks UI 2.0的全部功能。

    金蝶operamasks-ui(API)

    1、将operamasks-ui.war部署到符合Servlet 2.5/JSP2.1的所有Web容器或J2EE应用服务器(如:Tomcat) 2、war包部署成功后访问:http://127.0.0.1:8080/operamasks-ui/

    operamasks-ui_demo

    operamasks-ui的demo程序,能够直接部署,运行。查看om-ui上优秀的标签。

    operamasks-ui

    "Operamasks-UI" 是一个专为Opera浏览器设计的用户界面增强插件的源代码包,其版本为1.2,存储在一个名为"operamasks-ui-1.2.zip"的压缩文件中。这个插件的目标是提供更加个性化、高效且易用的浏览体验。在了解这个...

    operamasks-ui-2.0.zip

    总的来说,"operamasks-ui-2.0.zip" 提供了一个基于JavaScript的用户界面解决方案,包含丰富的组件和工具,适用于需要交互性界面的Web项目。其开源许可证使得开发者可以在遵守相应条款的情况下自由使用和定制,而...

    operamasks-ui 最新.

    operamasks-ui 最新.完成的,下载下来直接可以点击查看,跟官网一模一样

    operamasks-ui-2.1-demo

    总之,“operamasks-ui-2.1-demo”提供了一个实践OperaMasks UI框架的平台,对于想要提升浏览器扩展开发技能的开发者和设计师来说,这是一个宝贵的资源。通过阅读readme.txt和运行war文件,我们可以深入学习这个框架...

    operamasks-ui-2.0-demo--.zip

    这个压缩包文件 "operamasks-ui-2.0-demo--.zip" 包含了用于演示和实践如何使用Opera Masks UI 2.0版本的资源和代码示例。 Opera Masks UI 是一个强大的工具,它允许开发者通过自定义界面元素和交互方式来增强...

    operamasks-ui-master.zip

    【标签】"operamasks-ui" 直接关联了这个框架的名字,它是这个压缩包的核心内容,是一个专为Web界面设计的组件库,提供了丰富的UI元素和交互设计,使得开发者能够快速构建出符合现代审美和功能需求的页面。...

    operamasks-ui-2.1.zip

    JavaScript文件用于实现交互逻辑和功能,CSS文件则用于定义样式和布局,共同决定了用户界面的外观和行为。 6. **swf** 文件夹:SWF文件通常是Adobe Flash的内容,这可能意味着"Operamasks UI 2.1"在设计时考虑到了...

    OperaMasks-UI-Guide帮助文档

    OperaMasks-UI-Guide帮助文档

    operamasks-ui和struts2、springMVC框架整合实践

    springMVC框架开发 博文链接:https://lyg8266.iteye.com/blog/1404821

    operamasks-ui-2.0-doc

    通过深入学习这份"operamasks-ui-2.0-doc",开发者不仅可以掌握Operamasks的集成和自定义方法,还能了解到区块链技术在Web应用中的实际应用,这对于构建基于以太坊或其他区块链平台的DApp至关重要。同时,了解这些...

    Operamasks-UI

    OM-UI是一个基于jQuery的前端组件库。它提供了丰富的组件,包括各种表单组件、布局组件、功能性组件等。它旨在帮助用户快速构建企业应用。它是简单易用的,并配有丰富的文档、示例和详实的开发手册。最重要的一点,...

    OperaMasks-UI-Guide.rar

    《OperaMasks UI指南》是针对OperaMasks用户界面的一...通过深入阅读《OperaMasks UI指南》,用户不仅能掌握这款浏览器扩展的基本操作,还能了解其高级功能和个性化设置,从而充分发挥OperaMasks的潜力,提升浏览体验。

    扩展OperamasksUI的grid的排序和显示detail属性

    这篇博客“扩展OperamasksUI的grid的排序和显示detail属性”显然聚焦于如何增强Operamasks UI框架的功能,特别是其grid组件。Operamasks UI可能是一个用于构建Web应用的开源库,提供了丰富的组件和功能,便于开发者...

    operamasks-faces_1.0

    "Operamasks-faces_1.0" ...同时,这也展示了开发者如何通过浏览器扩展来丰富和扩展浏览器的功能,满足用户多样化的需求。对于想要学习浏览器扩展开发的人员来说,这是一个很好的实例,可以研究其内部结构和工作原理。

Global site tag (gtag.js) - Google Analytics