easyui组件解析的实现思路

1. 每一个easyui组件都有一个以其组件名称命名的函数例如:linkbutton:

这个函数的功能有三部分:

$.fn.linkbutton = function(options, param){

// 第一个功能:这个函数可以接受一个字符串参数,这个字符串参数通常就是

// 这个组件所提供的函数的名称,通过下面的代码就实现了,对该函数的调用

// 其实这里可以这样实现的原因是,js 不是一种强类型语言,所以他不会检查函数传递参数的类型。这就给函数传递的参数的作用可以动态变化。

????????if (typeof options == ‘string‘){

????????????return $.fn.linkbutton.methods[options](this, param);

????????}

????????

????????options = options || {};

????????return this.each(function(){

// 这里的this其实就是使用选择器,选中的DOM元素。此时下面的方法(这个方法来自jquery)就是获取,当前元素是是否绑定了 linkbutton 这个数据,如果没有绑定下面的 state 就是 undefied.显然第一次创建 linkbutton 对象时,肯定是未绑定的。所以下面的if判断就是失败的。流程跳转到else部分。

????????????var state = $.data(this, ‘linkbutton‘);

????????????if (state){

????????????????$.extend(state.options, options);

????????????} else {

// 下面的代码就是将,linkbutton 对象的配置属性绑定到 当前的DOM对象上。可以看到,对象的属性来自三个方面:

1. $.fn.linkbutton.defaults 这是对象默认的配置属性。在对象的实现文件中就有,例如:(来自 jquery.linkbutton.js)

????$.fn.linkbutton.defaults = {

????????id: null,

????????disabled: false,

????????plain: false,

????????text: ‘‘,

????????iconCls: null

????};

2. $.fn.linkbutton.parseOptions(this) ,这个通过将this对象传递给parseOptions这个函数后,在DOM元素的html标签上获取的配置属性例如:

<a href="#" id="btn" iconCls="icon-search">easyui</a>

3. options. 这个是 linkbutton这个函数被调用时,通过参数传递进来的。通常在使用js代码生成linkbutton时,就会将这个参数传递。例如:

$(‘#btn‘).linkbutton({plain:true});

最后,这样一句调用:

????????????????$.data(this, ‘linkbutton‘, {

????????????????????options: $.extend({}, $.fn.linkbutton.defaults, $.fn.linkbutton.parseOptions(this), options)

????????????????});

就把,所有有关该组件的配置属性全部的传递到 DOM 对象的 options 属性上。此时就可以使用 $.data(this, ‘linkbutton‘) 来获得关于该对象的配置属性。

????????????????$(this).removeAttr(‘disabled‘);

????????????}

// 第三部分创建linkbutton.

????????????createButton(this);

????????});

????};

2. 下面来看看对象的创建 function createButton(target)

function createButton(target) {

// 1. 获得对象的配置属性

????????var opts = $.data(target, ‘linkbutton‘).options;

// 2. 清空对象的所有子元素。

????????$(target).empty();

// 3. 设置对象的标准配置演示。

????????$(target).addClass(‘l-btn‘);

// 4. 依据对象的options来设置DOM的属性。

????????// 设置ID

????????if (opts.id){

????????????$(target).attr(‘id‘, opts.id);

????????} else {

//????????????$.fn.removeProp ? $(target).removeProp(‘id‘) : $(target).removeAttr(‘id‘);

//????????????$(target).removeAttr(‘id‘);

????????????$(target).attr(‘id‘, ‘‘);

????????}

????????// 设置显示样式

????????if (opts.plain){

????????????$(target).addClass(‘l-btn-plain‘);

????????} else {

????????????$(target).removeClass(‘l-btn-plain‘);

????????}

????????// 设置显示文本以及文本旁边的图标

????????if (opts.text){

????????????$(target).html(opts.text).wrapInner(

????????????????????‘<span class="l-btn-left">‘ +

????????????????????‘<span class="l-btn-text">‘ +

????????????????????‘</span>‘ +

????????????????????‘</span>‘

????????????);

????????????if (opts.iconCls){

????????????????$(target).find(‘.l-btn-text‘).addClass(opts.iconCls).css(‘padding-left‘, ‘20px‘);

????????????}

????????} else {

????????????$(target).html(‘&nbsp;‘).wrapInner(

????????????????????‘<span class="l-btn-left">‘ +

????????????????????‘<span class="l-btn-text">‘ +

????????????????????‘<span class="l-btn-empty"></span>‘ +

????????????????????‘</span>‘ +

????????????????????‘</span>‘

????????????);

????????????if (opts.iconCls){

????????????????$(target).find(‘.l-btn-empty‘).addClass(opts.iconCls);

????????????}

????????}

// 设置按钮的启用禁用。

????????$(target).unbind(‘.linkbutton‘).bind(‘focus.linkbutton‘,function(){

????????????if (!opts.disabled){

????????????????$(this).find(‘span.l-btn-text‘).addClass(‘l-btn-focus‘);

????????????}

????????}).bind(‘blur.linkbutton‘,function(){

????????????$(this).find(‘span.l-btn-text‘).removeClass(‘l-btn-focus‘);

????????});

????????

????????setDisabled(target, opts.disabled);

????}

到此为止,一个linkbutton组件就创建好了。

3. 看看linkbutton 是如何解析页面配置属性的。

$.fn.linkbutton.parseOptions = function(target){

????????var t = $(target);

????????return $.extend({}, $.parser.parseOptions(target, [‘id‘,‘iconCls‘,{plain:‘boolean‘}]), {

????????????disabled: (t.attr(‘disabled‘) ? true : undefined),

????????????text: $.trim(t.html()),

????????????iconCls: (t.attr(‘icon‘) || t.attr(‘iconCls‘))

????????});

????};

从上面的代码可以看到,其实就是通过jquery的选择器,获取,预定义属性的值,然后创建配置对象。这就实现了页面配置属性的解析。

4. 创建组件的两种方法

在easyui中创建组件有两种方法:

4.1 调用组件的创建函数,例如:

1. $(‘#btn‘).linkbutton({

2. plain:true

3. });

4. $(‘#btn‘).linkbutton(‘disable‘); // 禁用此 button

5. $(‘#btn‘).linkbutton(‘enable‘); // 启用此 button

在js文件调用上面的代码。即可创建一个linkbutton同时可以设置属性。此时我们知道其实就是调用了 linkbutton 函数。所以这里的组件创建其实是我们主动创建的。

4.2 html 写法

<a href="#" id="btn" iconCls="icon-search">easyui</a>

我们非常好奇的是:这种写法对象是怎样被创建的。其实这里就用到了easyui的解析器。上面的html加载完毕之后就会调用,解析器,来解析页面,从而创建相应的easyui组件.easyui的解析器就是jquery.parser.js.这个文件中定义了一个parse方法这个方法就是用来解析页面中的html标签创建的easyui组件的.那么这个方法在何时被调用呢.我们查看 jquery.easyui.min.js 文档,搜索 parser 发现了下面的代码:

$(function(){

if(!window.easyloader&&$.parser.auto){

$.parser.parse();

}

});

由此当一个html页面包含 jquery.easyui.min.js 文件时,则页面加载完毕之后,就会调用 $.parser.parse(); 来执行页面解析,将easyui组件解析出来。

下面就来看看 parse 函数是如何实现页面解析的。

5. parser.parse 函数(定义在 jquery.parser.js文件中)

这个函数实现了两个功能就是加载,easyui预定义组件和动态加载组件。其核心代码如下:

// 下面的数组就是 easyui 预定义的组件。

plugins:[‘draggable‘,‘droppable‘,‘resizable‘,‘pagination‘,

???????? ‘linkbutton‘,‘menu‘,‘menubutton‘,‘splitbutton‘,‘progressbar‘,

???????????????? ‘tree‘,‘combobox‘,‘combotree‘,‘combogrid‘,‘numberbox‘,‘validatebox‘,‘searchbox‘,

???????????????? ‘numberspinner‘,‘timespinner‘,‘calendar‘,‘datebox‘,‘datetimebox‘,‘slider‘,

???????????????? ‘layout‘,‘panel‘,‘datagrid‘,‘propertygrid‘,‘treegrid‘,‘tabs‘,‘accordion‘,‘window‘,‘dialog‘

????????],

// 下面就是 parse 函数的定义

????????parse: function(context){

????????????var aa = [];

// 加载组件的算法也非常简洁:对于加载函数来说,她也不知道,页面存在那些easyui组件,所以,其加载策略就是,将 其所支持的所有组件轮询加载一边。如果对象存在,就调用创建函数。否则,就不创建。同时由于easyui提供一种按需加载的组件加载模式,所以当进行文档解析时,有可能,某个组件的js文件还没有被加载出来,所以首先将其保存的 数组 aa 中。后面再加载解析。

?

????????????for(var i=0; i<$.parser.plugins.length; i++){

????????????????var name = $.parser.plugins[i];

????????????????var r = $(‘.easyui-‘ + name, context);

????????????????if (r.length){

????????????????????if (r[name]){

???? // 调用组件的创建函数。

????????????????????????r[name]();

????????????????????} else {

????// 将还未加载的组件先保存起来。

????????????????????????aa.push({name:name,jq:r});

????????????????????}

????????????????}

????????????}

// 2. 按需加载所需要的组件。

????????????if (aa.length && window.easyloader){

????????????????var names = [];

????????????????for(var i=0; i<aa.length; i++){

????????????????????names.push(aa[i].name);

????????????????}

// 加载组件。之后调用创建函数,在页面上渲染组件。

????????????????easyloader.load(names, function(){

????????????????????for(var i=0; i<aa.length; i++){

????????????????????????var name = aa[i].name;

????????????????????????var jq = aa[i].jq;

????????????????????????jq[name]();//创建组件

????????????????????}

????????????????????$.parser.onComplete.call($.parser, context);

????????????????});

????????????} else {

????????????????$.parser.onComplete.call($.parser, context);

????????????}

????????}

?

easyloader其实也很简单,就是依据名称加载对应的js以及css文件。

5. 关于 easyui 的 datagrid 中的 formatter.

这个函数可以格式化单元格,但是,当我们在其中添加类似的

<a href="#" id="btn" iconCls="icon-search">value</a>

时却不能正确的解析成easyui组件,其实,根本原因是:由 formatter 的实现方法决定的,其实现代码如下:

var th=$(this);

formatter:(th.attr("formatter")?eval(th.attr("formatter")):undefined),

由此可将,其实他并没有再次做easyui的组件解析工作,所以要先上面的标签被解析成easyui组件,就必须,在数据加载完毕之后在,显示的解析该组件。其方法是:

onLoadSuccess实现这个事件,当数据加载成功时触发被触发。所以在这里调用:

linkbutton()函数即可。

6. 查看源代码之后,其实我们可以这样调用函数:

<a href="#" id="btn" class="easyui-linkbutton" iconCls="icon-search">wow</a>

?

var btn = $("#btn");

btn.linkbutton.methods[‘disable‘](btn);

时间: 2024-10-28 09:47:59

easyui组件解析的实现思路的相关文章

Navi.Soft20.WebMVC4操作手册(含EasyUI组件源码)

阅读导航 Navi.Soft20.WebForm操作手册http://www.cnblogs.com/xiyang1011/p/4049711.html Navi.Soft20.WinForm操作手册http://www.cnblogs.com/xiyang1011/p/3972118.html Navi.Component.工作流开发手册(含示例)http://www.cnblogs.com/xiyang1011/p/3820038.html Navi.Component.DataWindow

一些easyui组件不生效或者不能取值的问题解释

本文转自http://www.cnblogs.com/iyangyuan/p/3358239.html,工作中遇到了动态添加class样式的问题,看到这篇文章写的很好.特此转发. 这是个小菜在实际工作中遇到的问题,相信很多EasyUI新手很可能也遇到这样的问题,因此小菜觉得有必要拿出来分享一下. 这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$("#id").val()这种形式,居然拿不到文本框的值! 经过度娘的帮助,发现可以用$("#id&q

EasyUI学习总结(五)——EasyUI组件使用

EasyUI学习总结(五)--EasyUI组件使用 一.EasyUI组件的简单介绍 easyUI提供了很多组件让我们使用,如下图所示: 使用这些组件可以帮助我们快速地进行项目开发,下面以一个用户登录程序为例讲解EasyUI组件的使用 二.EasyUI组件的使用 2.1.创建测试的JavaWeb项目 2.2.编写测试代码 编写一个用户登录页面Login1.html,用于输入用户名和密码进行登录,使用JQuery的ajax方法异步提交表单 Login1.html的代码如下: 1 <!DOCTYPE

日志组件解析

日志组件解析 NetCore中的日志(1)日志组件解析 0x00 问题的产生 日志记录功能在开发中很常用,可以记录程序运行的细节,也可以记录用户的行为.在之前开发时我一般都是用自己写的小工具来记录日志,输出目标包含控制台.文本文件.数据库,一般都是创建全局的Logger,在需要记录日志的地方调用相应的Logger输出至相应目标.遇到输出目标多了有时候也感觉挺麻烦的,不过也还能接受.开始学习.NetCore后接触到了日志记录框架(Logging组件),虽然完全可以用之前的方式记录日志,不过应该使用

.NetCore中的日志(1)日志组件解析

.NetCore中的日志(1)日志组件解析 0x00 问题的产生 日志记录功能在开发中很常用,可以记录程序运行的细节,也可以记录用户的行为.在之前开发时我一般都是用自己写的小工具来记录日志,输出目标包含控制台.文本文件.数据库,一般都是创建全局的Logger,在需要记录日志的地方调用相应的Logger输出至相应目标.遇到输出目标多了有时候也感觉挺麻烦的,不过也还能接受.开始学习.NetCore后接触到了日志记录框架(Logging组件),虽然完全可以用之前的方式记录日志,不过应该使用更通用的方式

OpenStack入门 之 各组件解析

学习目标: 掌握 OpenStack 的各组件的架构和功能 本次笔记的内容有: Nova 组件解析 Swift 组件解析 Cinder 组件解析 Neutron 组件解析 Horizon 组件解析 Glance 组件解析 Keystone 组件解析 是常用的 7 个组件: 负责虚拟机创建.管理和销毁.提供计算资源服务的 Nova: 提供对象存储服务的分布式存储 Swift: 提供块存储服务的 Cinder: 提供虚拟机镜像管理和存储服务的 Glance: 软件定义网络项目 Neutron: 提供

三、OpenStack入门 之 各组件解析

OpenStack入门 之 各组件解析 写在前面 学习目标: 掌握 OpenStack 的各组件的架构和功能 本次笔记的内容有: Nova 组件解析 Swift 组件解析 Cinder 组件解析 Neutron 组件解析 Horizon 组件解析 Glance 组件解析 Keystone 组件解析 是常用的 7 个组件: 负责虚拟机创建.管理和销毁.提供计算资源服务的 Nova: 提供对象存储服务的分布式存储 Swift: 提供块存储服务的 Cinder: 提供虚拟机镜像管理和存储服务的 Gla

四、OpenStack入门 之 各组件解析(进阶)

OpenStack入门 之 各组件解析(进阶) 学习目标: 掌握更多组件的架构和功能 本次笔记的内容有: Ceilmeter 组件解析 Heat 组件解析 Trove 组件解析 Sahara 组件解析 Ironic 组件解析 1. Ceilometer组件解析 又称为 OpenStack Telemetry(远程测量收集数据),是 OpenStack 里面做 metering 的项目.Ceilometer 的主要目的是 为计费提供数据支持. OpenStack 本身不提供计费的功能,Ceilom

web项目添加easyui组件报错

创建web项目添加easyui组件到webRoot下后整个easyui组件报错 出现x的原因是eclipse检查了压缩版的jquery.min.js,而压缩版的语法格式很紧凑,eclipse反应不过来报错 可以右键easyui---->myeclipse---->exclude from validation  忽略报错就可以了,不影响组件的使用 原文地址:https://www.cnblogs.com/naidi/p/10477801.html