首页 > Web开发 > 详细

扩展 jquery miniui 组件实现自动查询数据

时间:2017-01-06 10:37:44      阅读:1117      评论:0      收藏:0      [点我收藏+]

主题

  之前写过一篇文章分享了公司basecode查找数据后台是怎么实现的(http://www.cnblogs.com/abcwt112/p/6085335.html).今天想分享一下公司前台是怎么扩展jquery miniui组件去配合后台实现自动查找数据的.

 

一个使用例子

项目中多多少少会遇到要下拉一些数据(不只是下拉,可能还有选择框等等).

技术分享

这些数据来自数据库里的某张代码表(当然也可以是复杂的SQL查询).这些数据写死在前台明显是不可能的,因为不同环境下配置的数据可能不同.但是为了每个下拉框去写一个Controller方法,Service方法.Dao方法...好像代价又太大了,而且他们具有一定的同性.这就是Basecode的存在的一个原因.

 

前台实现

后台的实现请参考我另外一篇文章,这篇文章主要分享下怎么扩展jquery miniui组件(miniui是类似于jquery easyui的一个前台JS框架)来实现前台自动发送请求加载数据实现basecode的下拉.

jquery miniui不是开源的,所以自己写组件继承起来比较蛋疼...但是多多少少还是可以做一些简单的扩展的.

 

一个最简单的代码表下拉的例子

实现basecode自动下拉的主要原理是利用了beforeload事件.

我们自己定义的组件继承了原本miniui的组件,重写了部分方法,在组件在初始化的时候额外加入了beforeload事件并触发,这样这个组件就会自动去后台查找数据了.

 1 mini.extend(framework.component.ComboList , mini.ComboBox , {
 2     
 3     codeType : "", //绑定代码类型
 4     
 5     remote : false, //是否从远端加载数据
 6     
 7     textField : "label",
 8     
 9     uiCls: "mini-ext_combolist",
10     
11     valueField : "value",
12     
13     queryparam : {},
14     
15     /**
16      * 重定义加载数据的方法,根据codeType指定的加载数据
17      */
18     load : function(data){
19         if(this.codeType && this.codeType.length > 0){
20             if(basecode[this.codeType] && !this.remote){
21                 this.setData(basecode[this.codeType]);
22             }else{
23                 this.setUrl(common.getBascodeUrl()+"/"+this.codeType);
24             }
25         }
26     },
27     
28     set : function(kv){
29         var me = this;
30         framework.component.ComboList.superclass.set.call(this,kv);        
31         me.on(‘beforeload‘,function(e){
32             e.type = ‘POST‘;
33             e.dataType = ‘json‘;
34             e.contentType = ‘application/json‘;
35             e.data = mini.encode(this.queryparam);
36         });
37         this.load({});
38 
39     },
40     
41     setCodeType: function (codeType) {
42         this.codeType = codeType;
43     },
44     
45     getCodeType : function(){
46         return this.codeType ; 
47     },
48     getAttrs: function (el) {
49         
50         var attrs = framework.component.ComboList.superclass.getAttrs.call(this, el);
51         mini._ParseString(el, attrs , [‘codeType‘]);
52         mini._ParseString(el, attrs , [‘param‘]);
53         var param = attrs[‘param‘];
54         if(param){
55             var cotrolids = param.match(common.PARAM_CMP_VALUE_REGEX);
56             if(cotrolids && cotrolids.length > 0){
57                 $.each(param.match(common.PARAM_CMP_VALUE_REGEX),function(i,item){
58                     var id = ‘#‘+item.replace(/#/gi,‘‘);
59                     var tempobj = mini.get(id);
60                     if(tempobj && tempobj.value){
61                         param = param.replace(item , tempobj.getValue());
62                     }
63                 });
64             }
65             this.queryparam =  mini.decode(param) != ‘undefined‘ ? mini.decode(param) : "";
66         }
67         attrs[‘textField‘] = attrs[‘textField‘] || ‘label‘;
68         attrs[‘valueField‘] = attrs[‘valueField‘] || ‘value‘;
69         mini._ParseBool(el, attrs,[‘remote‘]);
70         return attrs;
71 
72     }
73     
74 });
75 
76 mini.regClass(framework.component.ComboList , ‘ext_combolist‘);

完整的一个扩展的组件代码如上面.

 

当组件被渲染的时候:

 

第一个被调用的方法是L48的getAttrs方法,这个方法的用处就是把你页面上HTML标签比如input里面的各种属性解析成JS对象里面的属性.

比如你<input codeType="ENUM_SEX">那codeType就会被解析成JS对象的一个属性,{codeType:"ENUM_SEX"}.当然.不同框架的解析方法肯定不同,所以这里并不需要仔细研究(而且也没有源码).

最主要的属性是codeType,当然param这些也有用处(param里的key和value相当于是查询SQL where里面的条件).但是最简单的例子里不需要用到这些额外的参数,只要知道codeType就能知道basecode里去查哪张表了(详见另外一篇文章)

 

第二个被调用的方法是L28 set方法:set的作用就是把之前getAttrs取出来的JS对象的各种属性设置到miniui组件的属性中去.所以getAttrs返回的值就是set方法的入参.

在这里除了调用父组件的set方法完成基本的set之外,额外做了一个操作,就是最核心的beforeload事件.为自定的组件绑定了beforeload事件.

beforeload事件里主要是定义了ajax请求的一些参数.比如dataType是json等等..

 

第三个调用的当然是L18 load方法.它是在set方法最后一行被调用的

load方法里因为我们设置了codeType又设置了remote为true,所以会走else里面的代码.即从远程服务器端加载数据.

当我们调用setUrl方法以后miniui组件去发起get请求查找basecode的Controller的数据.后续后台流程请参考另外一篇文章.

至此前台请求发送完毕,把返回的数据根据textField和valueField显示到页面上即可.

 

当组件查询的值需要依赖于其他组件的时候(多级联动)

多级联动的情况在现实中还是比较常见的,公司本身扩展的组件也不是支持的很好,旁边小哥也自己扩展了一个,仍然有一些BUG.然后我又在他们的基础上修改了一下.(大部分时候开发还是自己去写valuechange事件,而不是自动多级联动)

技术分享

多级联动和一般的查代码表的区别在于,多级联动的时候你后面的下拉框的查询的值要依赖于前面的值.

比如上面3个组件.大类A,种类B,小类C.

b能下拉出什么值依赖于a,c依赖于b.

所以我们在组件里要有个属性记录当前组件依赖的组件.

比如组件b的html标签:

<input baseValue="#a组件的id#" ........>
getAttrs: function (el) {
    ..........
    this.baseValue = attrs[‘baseValue‘];
    ...............
}

我们用的是baseValue.

当然在getAttrs里直接set属性是不好的,应该在set那个方法里去设置.不过这样做也没啥问题(反正也能用).

this.on(‘beforeload‘,function(e){
...............
var tmpBaseValue = this.baseValue; ............各种加工tmpBasevalue this.queryParam = {}; this.queryParam.parent = (e.params && e.params[‘value‘]) || tmpBaseValue; if(this.queryParam.initParam != undefined){ this.queryParam.initParam = (e.params && this.queryParam.initParam) ? null : this.queryParam.initParam; } var param = {}; $.extend(true, param,this.queryParam );
................
}

然后在beforeload事件里把baseValue对应的id的miniui组件的getValue值合并到param里(中间处理逻辑被我省略了..因为不同框架处理逻辑肯定不同,这里也没啥通用性).最后会发送给后台.这样在查询组件b的basecode的值的时候还会附带上组件a的值作为查询条件之一.

 

多级联动还有个小特点就是你选了a,最好要把b的值清空.

这里是用blur事件来做的.

         var id = ‘#‘+this.baseValue.replace(/#/gi,‘‘);
                var tempobj = mini.get(id);
                if(tempobj){
                    tempobj.on("blur",function(){
                        if(!tempobj.oldValue || (tempobj.oldValue && tempobj.getValue() != tempobj.oldValue)){
                            tempobj.oldValue = tempobj.getValue();
                            me.setData([]);
                            me.setValue("");
                            me.setUrl(me.getUrl());
                        }
                    });
                }

根据baseValue找到依赖的组件,然后为组件绑定blur事件,当依赖组件的焦点丢失的时候(这个时候肯定是操作过组件,并且新选择的值和原本的值不同),触发blur事件,更新当前组件的值.

不过这里只更新了当前组件,并没有修改依赖于当前组件的组件的值,算是有点瑕疵吧.

 

扩展 jquery miniui 组件实现自动查询数据

原文:http://www.cnblogs.com/abcwt112/p/6251075.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!