65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JSON 和过滤器管理器进行 JavaScript 过滤

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (6投票s)

2010 年 9 月 9 日

CPOL

2分钟阅读

viewsIcon

138440

downloadIcon

1064

创建 C# 中动态过滤机制的第一部分。

xFilter.jpg

引言

本文将解释一个简单的客户端过滤框架,可以在任何页面中实现,以获得易于使用的过滤器。

背景

我正在寻找一些可以帮助我创建应用程序的控件。最适合我的控件是 jqGrid - 一个 jQuery 插件。jqGrid 以表格形式显示 JSON 数据源,并带有过滤和排序功能。为此,我们必须定义一个列模型(参见示例) - 当然,以 JSON 格式。

colModel:[
   	{name:'id',index:'id', width:60, sorttype:"int"},
   	{name:'name',index:'name', width:100, editable:true},
   	{name:'note',index:'note', width:150, sortable:false}		
  ]

Using the Code

不幸的是,jqGrid 的过滤功能并不像我需要的那么复杂。一个过滤器是一个 JSON 对象,格式如下:类型

{ "groupOp": "and",
      "rules": [
        { "field": "name", "op": "eq", "data": "Romania" }, 
        { "field": "id", "op": "le", "data": "1"}
      ]
}

它基本上是一组使用逻辑运算符分组的规则:“OR”或“AND”。对于简单的搜索,这个过滤器可能就足够了,但任何更复杂的内容都需要这样的组的树。所以让我们将一组规则数组添加到这个结构中。现在我们有了所需的树结构,并且仍然支持正常的 jqGrid 过滤器。假设我们需要一个像这样的过滤器

(name == "John" AND age > 30) OR (name == "Doe" AND age < 30) OR name == "Joe"

首先请注意,在组之间以及在组和规则之间,我们必须使用相同的逻辑运算符,否则我们将不得不将它们隔离在一个子组中。上面的公式将映射到

{ "groupOp": "or",
      "groups": [
		{ "groupOp": "AND", 
		  "rules": [
		      { "field": "name", "op": "eq", "data": "John" },
			  { "field": "age", "op": "gt", "data": "30" }
		  ]
		},
		{ "groupOp": "AND", 
		  "rules": [
		      { "field": "name", "op": "eq", "data": "Doe" },
			  { "field": "age", "op": "lt", "data": "30" }
		  ]
		}
	  ]
      "rules": [{ "field": "name", "op": "eq", "data": "Joe" }]
}

如我所说,我们有两种类型的运算符:组运算符和规则运算符。唯一的组运算符是“OR”和“AND”。作为规则运算符,我们有:eq(等于)、us(不同于)、lt(小于)等,以及字符串运算符:cn(包含)、sw(以...开头)等。上面的内容可以很容易地转换为更接近 JavaScript 的语法,通过使用函数

(eq(item.name, "John") && gt(item.age, "30")) || 
	(eq(item.name, "Doe") && lt(item.age, "30")) || eq(item.name, "Joe")

请注意,所有实体字段都以“item.”为前缀。让我们定义必要的 JavaScript 函数

function eq(d1, d2) { return d1 == d2; }
function lt(d1, d2) { return d1 < d2; }
function gt(d1, d2) { return d1 > d2; }

现在我们可以遍历一个 JSON 对象并评估上面的公式。

var jsonItems = [
	{"name": "John", "age": "18"},
	{"name": "Amanda", "age": "21"},
	{"name": "Dave", "age": "31"}
];

var expression = '(eq(item.name, "John") && gt(item.age, "30")) || 
	(eq(item.name, "Doe") && lt(item.age, "30")) || eq(item.name, "Joe")';

var newJsonItems = [];
for(var index = 0; index < jsonItems.length; index++){
	var item = jsonItems[index]; // define the item that will be evaluated
	if(eval(expression) == true){
		newJsonItems.push(item);
	}
}

到目前为止,我们有了逻辑,但我们需要一个 Web 用户界面来配置过滤器。幸运的是,我写了一个 JS 类来执行此操作:xFilter (参见附件)。要使用它,您只需要提供 DOM 父元素和列模型。

var colModel = [
	{ "name": "id"},// we only need this field, jqGrid requires the rest
	{ "name": "name"},
	{ "name": "note"}
];
var items = [
	{ "name": "Romania", "id": "1", "note": "ro" },
	{ "name": "Franta", "id": "2", "note": "fr"},
	{ "name": "Anglia", "id": "3", "note": "uk"},
	{ "name": "Italia", "id": "4", "note": "it" },
	{ "name": "Germania", "id": "5", "note": "ge" }
];
	
var f = new xFilter(document.getElementById("fil"),
{
	columns: colModel,
	onchange: function() {
		document.getElementById("message").innerHTML =	
			this.toUserFriendlyString();

		var resItems = f.Apply(items);
		var s = "";
		for (var i = 0; i < resItems.length; i++) {
			s += "," + resItems[i].name;
		}
		document.getElementById("message").innerHTML = s;
	}
});

如您所见,该类具有“onchange”事件,该事件在每次过滤器发生更改时触发。当然,可以使用“Apply”方法 - 其逻辑如上所示 - 来过滤 JSON 对象。

结论

希望您喜欢这篇文章。下一篇文章将在服务器端(C#)采用这种模型,我们将创建的过滤器将成为可以与 LINQ 实现一起使用的表达式树。

链接

创建动态过滤机制的 C# 第二部分。

© . All rights reserved.