使用 JSON 和过滤器管理器进行 JavaScript 过滤
创建 C# 中动态过滤机制的第一部分。

引言
本文将解释一个简单的客户端过滤框架,可以在任何页面中实现,以获得易于使用的过滤器。
背景
我正在寻找一些可以帮助我创建应用程序的控件。最适合我的控件是 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 实现一起使用的表达式树。