天天看點

ExtJs結合QBC,簡化工作量的一個嘗試

QBC中用得比較普遍的莫過于 property op value 這種形式

較常用的一些方法

ExtJs結合QBC,簡化工作量的一個嘗試

而在界面的表單上,我們的查詢,做成公共實作還是有較多方案的,不過問題在于像between,not等這類關系,并不能很好的控制,尤其是between,一個property對應兩個value,表示一個區間。

之前我做的一個項目中,前端使用extjs,背景索引部分使用compass,而compass與spring結合後,風格跟spring-hibernate,以及hibernate的qbc很像。

下面就以extjs3.2,以及compass進行簡要說明我的思路。

1、有一個這樣的查詢

ExtJs結合QBC,簡化工作量的一個嘗試

其中"公司名稱"是模糊比對,即"like"

"添加日期"是精确比對,即"eq"

當然,你也可以處理時間跨度的查詢,即between,不過這種方式使用">"、"<"相結合計較好實作。

like你也可以自己設定規則,如headLike,endLike等,隻要背景有相應的解析處理程式。

2、我希望界面能傳給背景這樣的一個資訊:

[{
	name:'companyName',
	value:'長江',
	relation:'like'
},{
	name:'createDate',
	value:'2011-08-03',
	relation:'eq'
}]      

我希望不需要每次都手工去拼寫這樣的JSON,ExtJs的FormPanel(實際上是BasicForm的方法)有提供這樣的一種方式擷取json,用以送出:

var formJSON = formPanel.getForm().getValues();      

可是通過這樣擷取到的JSON格式是:

{companyName:'長江',createDate:'2011-08-03'}      

這并不是我所希望的格式,我想要的是三元關系。

要得到三元關系JSON的效果,需要對ExtJs的BasicForm進行擴充,如下:

Ext.override(Ext.form.BasicForm, {
	getRelations : function(tarName, tarFun) {
		var _this = this;
		var form = this.el.dom;
		var fElements = form.elements
		  || (document.forms[form] || Ext.getDom(form)).elements, hasSubmit = false, encoder = encodeURIComponent, name, relation, data = [], type, hasValue;

		Ext.each(fElements, function(element) {
			  var record;
			  name = element.name;
			  type = element.type;
			  if (_this.findField(name)) {
				  relation = _this.findField(name).relation;
				  nullValue = _this.findField(name).nullValue;
				  hiddenValue = _this.findField(name).hiddenValue;
			  }
			  if (!element.disabled && name) {
				  if (/select-(one|multiple)/i.test(type)) {
					  Ext.each(element.options, function(opt) {
						    if (opt.selected) {
							    hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt
							      .getAttributeNode('value').specified;
							    data += String.format("{0}={1}&", encoder(name), encoder(hasValue
							        ? opt.value
							        : opt.text));
						    }
					    });
				  } else if (!(/file|undefined|reset|button/i.test(type))) {
					  if (!(/radio|checkbox/i.test(type) && !element.checked)
					    && !(type == 'submit' && hasSubmit)) {
						  var value = hiddenValue ? hiddenValue : element.value;
						  if (relation && value && value != '' && value != nullValue) {
							  if (/\./.test(name)) {
								  name = name.substring(0, name.indexOf('.'));
							  }
							  record = 'name=' + encoder(name) + '&value=' + encoder(value)
							    + '&relation=' + relation;
							  var json = Ext.urlDecode(record);
							  if (tarName == name && tarFun) {
								  json = tarFun(json);
							  }
							  data.push(json);
						  }
						  hasSubmit = /submit/i.test(type);
					  }
				  }
			  }
			  relation = null;
		  });
		return data;
	}
});      

使用的時候,form還是一樣的寫法,隻是多了一個relation屬性

this.formPanel = new Ext.form.FormPanel({
	    xtype : 'form',
	    title : '查詢區',
	    region : 'north',
	    height : 65,
	    layout : 'column',
	    frame : true,
	    items : [{
		      xtype : 'panel',
		      columnWidth : 0.4,
		      layout : 'form',
		      labelPad : 0,
		      labelWidth : 60,
		      items : [{
			        xtype : 'textfield',
			        name : 'company.companyName',
			        relation : 'like',
			        width : 100,
			        fieldLabel : '公司名稱',
			        anchor : '95%'
		        }]
	      }, {
		      xtype : 'panel',
		      columnWidth : 0.4,
		      layout : 'form',
		      labelPad : 0,
		      labelWidth : 60,
		      items : [{
			        xtype : 'datefield',
			        name : 'startDate',
			        relation : 'eq',
			        fieldLabel : '添加日期',
			        format : 'Y-m-d',
			        editable : false,
			        maxValue : new Date(),
			        anchor : '95%'
		        }]
	      }, {
		      xtype : 'panel',
		      items : [{
			        xtype : 'button',
			        columnWidth : 0.2,
			        text : '查詢',
			        iconCls : 'ux-icon-search',
			        handler : this.onQuery.createDelegate(this),
			        scope : this
		        }]
	      }],
	    keys : [{
		      key : Ext.EventObject.ENTER,
		      fn : this.onQuery.createDelegate(this),
		      scope : this
	      }]
    });      

送出時隻需要

var formJSON= this.formPanel.getForm().getRelations();
即可拿到對應的三元JSON串。
通過ajax方式送出,params可以如下設定:
params:{
    data:Ext.util.JSON.encode(formJSON),
    xxx:'其他參數'
}      

3、我希望背景能夠讀懂這樣格式的資料

當然,這裡實際是用compass提供的qbc,但若用在hibernate上亦是類似。

如果你不喜歡直接傳JSON作為參數,亦可做一次轉換。Map或者Bean集合。這裡隻是想說明問題。

public static CompassBooleanQueryBuilder generateQueryBuilder(Class entity, CompassSession session, JSONArray queryArray) {
		CompassQueryBuilder queryBuilder = session.queryBuilder();
		CompassBooleanQueryBuilder query = queryBuilder.bool();
		query.addMust(queryBuilder.term("alias",entity.getSimpleName()));
		if (null==queryArray || queryArray.size()==0) {
			logger.debug("[OSEM]  "+query.toQuery().toString()+"  [OSEM]");
			return query;
		}
		for (int i = 0; i < queryArray.size(); i++) {
			java.lang.reflect.Field field;
			String name = queryArray.getJSONObject(i).getString("name");
			try {
				field = entity.getDeclaredField(name);
			} catch (NoSuchFieldException e) {
				try {
					field = entity.getSuperclass().getDeclaredField(name);
				} catch (NoSuchFieldException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
	                throw new NoSuchElementException("error.class.no.field");
				}
			}
			Class type = field.getType();
			Object value = queryArray.getJSONObject(i).get("value");
			String relation = queryArray.getJSONObject(i).getString("relation");
			if (relation.equals("like")) {
				query.addShould(queryBuilder.term(name, generateSpace(value.toString())+splitStrings(value.toString())));
			}else if (relation.equals("eq")) {
				query.addMust(queryBuilder.term(name, value));
			}else if (relation.equals("<")) {
				query.addMust(queryBuilder.lt(name, value));
			}else if (relation.equals("<=")) {
				query.addMust(queryBuilder.le(name, value));
			}else if (relation.equals(">")) {
				query.addMust(queryBuilder.gt(name, value));
			}else if (relation.equals(">=")) {
				query.addMust(queryBuilder.ge(name, value));
			}else if (relation.equals("between")) {
				JSONArray array = (JSONArray)value;
				query.addMust(queryBuilder.between(name, array.getString(0), array.getString(i), true));
			}
		}
		logger.debug("[OSEM]  "+query.toQuery().toString()+"  [OSEM]");
		return query;
	}
           

這樣處理了之後,基本ExtJs表單配置完成,即可,而且不局限于Bean一一映射的那一類查詢方式。

http://raywithu.iteye.com/admin/blogs/1139513

繼續閱讀