原文地址:http://www.easyui.info/archives/1664.html

对jQuery EasyUI有一定了解的话,应该知道基本上每一个组件都有一个"options"方法用于返回该组件实例的属性。这些属性决定了组件实例将如何展现和运作。

不过EasyUI的属性取值渠道比较多,多得有些让人眼花缭乱,渠道多有好处也有坏处,好处就是很灵活,坏处就是容易乱,比如说多种渠道设置同一个属性时,到底以哪种渠道设置的属性为准呢?

本篇文章就来较为详细的做一下总结,注意,我们只关注属性有哪些渠道获取,各种渠道的优先级,属性的类型等,我们并不关注属性是如何影响组件实例的。

属性获取渠道

  • 【渠道1】组件定义时设置的默认值,组件没有实例化就是相当于"类"了,各种属性设置了默认值;
  • 【渠道2】组件实例宿主DOM对象的data-options属性,data-options是以json串的方式设置属性的,很灵活;
  • 【渠道3】组件实例宿主DOM对象的属性,也就是html标签的各个属性(style和data-options例外)
  • 【渠道4】组件实例宿主DOM对象的style属性;
  • 【渠道5】如果组件的实例化是通过javascript的话,组件构造函数的的入参也可以设置组件实例属性

组件的构造函数

这么多种方式设置组件实例的属性,到底他们的优先级是什么样的?我们拿panel组件的源码来分析,看pane构造函数代码,因为一切都是从构造函数开始的:

  1. /**
  2. * panel组件的构造函数
  3. * @param options
  4. * @param param
  5. * @returns {*}
  6. */
  7. $.fn.panel = function(options, param){
  8. if (typeof options == 'string'){
  9. return $.fn.panel.methods[options](this, param);
  10. }
  11. options = options || {};
  12. return this.each(function(){
  13. var state = $.data(this, 'panel');
  14. var opts;
  15. if (state){//已经初始化过
  16. //属性值用新传入的覆盖
  17. opts = $.extend(state.options, options);
  18. state.isLoaded = false;
  19. } else {//还未初始化
  20. //获取panel组件实例的属性列表
  21. opts = $.extend({}, $.fn.panel.defaults, $.fn.panel.parseOptions(this), options);
  22. $(this).attr('title', '');
  23. state = $.data(this, 'panel', {
  24. options: opts,
  25. panel: wrapPanel(this),
  26. isLoaded: false
  27. });
  28. }
  29. addHeader(this);
  30. setProperties(this);
  31. if (opts.doSize == true){
  32. state.panel.css('display','block');
  33. setSize(this);
  34. }
  35. if (opts.closed == true || opts.minimized == true){
  36. state.panel.hide();
  37. } else {
  38. openPanel(this);
  39. }
  40. });
  41. };

关键性代码就是22行,使用了jQuery的extend函数,这行代码的信息量很大,我们可以轻松地看出,组件默认值的优先级最低;如果是javascript构造的组件实例,构造函数的入参优先级最高;夹在中间的是panel组件的属性转换器。

到这里,我们至少已经得出了一个简单结论:【渠道1】的优先级最低,【渠道5】的优先级最高。

组件的属性转换器

对于渠道2,3,4,我们则要进一步分析panel组件的属性转换器了,看它的代码:

  1. /**
  2. * panel组件的属性转换器
  3. * @param target 组件实例的宿主DOM
  4. * @returns {*}
  5. */
  6. $.fn.panel.parseOptions = function (target) {
  7. var t = $(target);
  8. return $.extend(
  9. //新空对象
  10. {},
  11. //公用的属性转换器
  12. $.parser.parseOptions(target, ['id', 'width', 'height', 'left', 'top',
  13. 'title', 'iconCls', 'cls', 'headerCls', 'bodyCls', 'tools', 'href',
  14. {cache: 'boolean', fit: 'boolean', border: 'boolean', noheader: 'boolean'},
  15. {collapsible: 'boolean', minimizable: 'boolean', maximizable: 'boolean'},
  16. {closable: 'boolean', collapsed: 'boolean', minimized: 'boolean', maximized: 'boolean', closed: 'boolean'}
  17. ]),
  18. //loadingMessage属性有什么特别之处,为什么要单独作为一个参数?
  19. {
  20. loadingMessage: (t.attr('loadingMessage') != undefined ? t.attr('loadingMessage') : undefined)
  21. }
  22. );
  23. };

又是用了jQuery的extend函数,直接看上去,得不到太多信息,extend函数有三个实参。第一个是为了拷贝到新对象上,第二个是公用的属性转换器,第三个则有些莫名其妙,单单的一个loadingMessage属性,为何要特殊处理?

公用的属性转换器

进一步看公用属性转换器的源码:

  1. /**
  2. * parse options, including standard 'data-options' attribute.
  3. *
  4. * @param target [DOM对象] 组件的宿主对象
  5. * @param properties [数组] 需要优先从宿主对象属性(不包含data-options属性)中取的opts列表
  6. *
  7. * calling examples:
  8. * $.parser.parseOptions(target);
  9. * $.parser.parseOptions(target, ['id','title','width',{fit:'boolean',border:'boolean'},{min:'number'}]);
  10. */
  11. function parseOptions(target, properties){
  12. var t = $(target);
  13. var options = {};
  14. //第一步:首先从data-options属性中取opts
  15. var s = $.trim(t.attr('data-options'));
  16. if (s){
  17. //兼容写大括号和不写大括号的写法
  18. if (s.substring(0, 1) != '{'){
  19. s = '{' + s + '}';
  20. }
  21. //利用Function函数将字符串转为化对象
  22. //到这里,我们第一次取值就完成了。
  23. options = (new Function('return ' + s))();
  24. }
  25. //第二步:如果properties不为空的话,则将properties中定义的属性增加或者覆盖到“第一步”中取到的属性列表中
  26. if (properties){
  27. var opts = {};
  28. for(var i=0; i<properties.length; i++){
  29. var pp = properties[i];
  30. //如果是字符串型
  31. if (typeof pp == 'string'){
  32. //width height left top四个属性从宿主对象的style属性中取值
  33. if (pp == 'width' || pp == 'height' || pp == 'left' || pp == 'top'){
  34. opts[pp] = parseInt(target.style[pp]) || undefined;
  35. } else {//其它情况直接从宿主对象的对应属性中取值
  36. opts[pp] = t.attr(pp);
  37. }
  38. } else {//布尔型或者数字型
  39. for(var name in pp){
  40. var type = pp[name];
  41. if (type == 'boolean'){//布尔型从宿主对象对应属性中取值,同时将属性值转为布尔型
  42. opts[name] = t.attr(name) ? (t.attr(name) == 'true') : undefined;
  43. } else if (type == 'number'){//数字型也从宿主对象对应属性中取值,同时将属性值转为浮数
  44. opts[name] = t.attr(name)=='0' ? 0 : parseFloat(t.attr(name)) || undefined;
  45. }
  46. }
  47. }
  48. }
  49. //第二步取得的结果覆盖到第一步取得的结果中
  50. $.extend(options, opts);
  51. }
  52. return options;
  53. }

原来主要的逻辑在公用的属性转换器里面,由代码我们可以清楚的看出【渠道3】和【渠道4】的优先级是高于【渠道2】的。

公用属性转换器的入参properties的用途究竟是什么呢?有代码可以看出,它是一个数组,数组元素只支持string和object两种,再 回头看,结合panel组件的属性转换器代码,不难可以看出,properties属性规范了组件实例各属性的数据类型,不过properties能规范 的类型只有boolen,number,string三种。

特殊的,对于width,height,left,top这四个属性,优先级最高的是【渠道4】,即最优先从style属性中取,且类型都为number型。

最后的结论

由上述总结,可以得出以下结论:

【渠道5】 > 【渠道4】 > 【渠道3】 > 【渠道2】 > 【渠道1】

到此处,我们关心的主要问题就算分析完了。不过还是遗留了一个问题,那就是panel组件的属性转换器中,为何loadingMessage属性不 放在公共的属性转换器里处理?单独作为参数传入的,number,bool,string这三种类型之外的属性,才有这必要。1.3.5的panel源码 为何要把loadingMessage属性特殊对待,本人是没有想明白。

注意:本文的分析基于data-options属性出世之后(印象中是1.2.6版本之后),文中代码是1.3.5版本的源码。

[转]浅谈jQuery EasyUI的属性设置的更多相关文章

  1. 浅谈jQuery easyui datagrid操作单元格样式

    今天项目上遇到问题,就是表格风格统一的问题,由于用了2个不同的框架,所以如果要大修比较麻烦,考虑到修改表格样式工作量会少很多,所以考虑修改jQuery easyui datagrid数据网格的样式. ...

  2. 浅谈jquery关于select框的取值和赋值

    浅谈jquery关于select框的取值和赋值   jQuery("#select_id").change(function(){}); // 1.为Select添加事件,当选择其 ...

  3. 浅谈WPF依赖项属性

    浅谈WPF依赖项属性 0. 引言 依赖项属性虽然在使用上和CLR属性一样,但是它是WPF特有的,不同于CLR属性.只是封装为我们常用CLR的属性,在语法使用上和CLR属性一样.WPF中一些功能:动画, ...

  4. 雷林鹏分享:jQuery EasyUI 数据网格 - 设置冻结列

    jQuery EasyUI 数据网格 - 设置冻结列 本实例演示如何冻结一些列,当用户在网格上移动水平滚动条时,冻结列不能滚动到视图的外部. 为了冻结列,您需要定义 frozenColumns 属性. ...

  5. 雷林鹏分享:jQuery EasyUI 数据网格 - 设置排序

    jQuery EasyUI 数据网格 - 设置排序 本实例演示如何通过点击列表头来排序数据网格(DataGrid). 数据网格(DataGrid)的所有列可以通过点击列表头来排序.您可以定义哪列可以排 ...

  6. 浅谈CSS3中display属性的Flex布局

    浅谈CSS3中display属性的Flex布局   最近在学习微信小程序,在设计首页布局的时候,新认识了一种布局方式display:flex 1 .container { 2 display: fle ...

  7. 浅谈jQuery中的Ajax

    浅谈jQuery中的Ajax 一.前言 jQuery 对 Ajax 操作进行了封装, 在 jQuery 中最底层的方法时 $.ajax(), 第二层是 load(), $.get() 和 $.post ...

  8. 浅谈Vue中计算属性(computed)和方法(methods)的差别

    浅谈Vue中计算属性(computed)和方法(methods)的差别 源码地址 methods方法和computed计算属性,两种方式的最终结果确实是完全相同 计算属性是基于它们的响应式依赖进行缓存 ...

  9. 车大棒浅谈jQuery源码(二)

    前言 本来只是一个自己学习jQuery笔记的简单分享,没想到获得这么多人赏识.我自己也是傻呵呵的一脸迷茫,感觉到受宠若惊. 不过还是有人向批判我的文章说,这是基本知识点,完全跟jQuery源码沾不上边 ...

随机推荐

  1. 【2016-10-12】【坚持学习】【Day3】【责任链模式】

    今天学习责任链模式 例子: 采购审批系统 采购单需要经过不同人审批 采购价格<500 部门经理审批 采购价格<1000 部门主任审批 采购价格<2000 副总审批 采购价格<5 ...

  2. AC日记——独木桥 洛谷 p1007

    题目背景 战争已经进入到紧要时间.你是运输小队长,正在率领运输部队向前线运送物资.运输任务像做题一样的无聊.你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在桥下欣赏士兵们.士兵 ...

  3. NGUI Label Color Code

    UILabel的颜色代码 NGUI的Label文档:http://www.tasharen.com/?page_id=166 you can embed colors in [RrGgBb] form ...

  4. WCF添加服务失败一则

    原因是本机开发IIS没有安装HTTPS证书 将红色的字注释掉就好了! <services> <service behaviorConfiguration="basicSer ...

  5. Could not load file or assembly 'MySql.Data.CF,

    Could not load file or assembly 'MySql.Data.CF, Version=6.4.4.0, Culture=neutral, PublicKeyToken=c56 ...

  6. javascript高级程序设计 读书笔记2

    第五章 引用类型 对象是引用类型的实例,引用类型是一种数据结构,将数据和功能组织在一起.描述的是一类对象所具有的属性和方法.对象是某个特定引用类型的实例,新对象是使用new操作符后跟一个构造函数俩创建 ...

  7. CocoaPods 哪些事

    一.CocoaPods的介绍 什么是CocoaPods CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必 ...

  8. 审核被拒(后台定位,autio,voip,发表朋友圈)

    APP上线审核被拒那些事(一) 2.3 - Apps that do not perform as advertised by the developer will be rejected 2.3 D ...

  9. linux系统root密码遗忘的情况下的解决办法

    机房一台centos系统的服务器,由于这台服务器的系统装了好长时间,且root密码中间更新过几次,后面去机房现场维护时,登陆密码遗忘了,悲催啊~ 没办法,只能开机进入“单用户模式”进行密码重置了. 下 ...

  10. js点击左右滚动+默认自动滚动类

    js点击左右滚动+默认自动滚动类 点击下载