我正在使用jQuery DataTable,并找到了一些很好的插件,使过滤更容易。它叫做ColumnFilter,可以在这里找到:
http://code.google.com/p/jquery-datatables-column-filter/
使用此插件非常简单。在声明DataTable之后,它就像这样配置:
oTable.columnFilter({
aoColumns: [
{ type: "number-range" },
{ type: "text" },
{ type: "text" }
]
});
当实际过滤数据源服务器端时,我需要知道在columnfilter插件中设置了哪些类型。这背后的原因是,我封装了一个通用的过滤方法,基本上允许我在服务器端控制器操作中的实体上执行此操作:
Public Function DataProviderAction(ByVal dataTableParams As JQueryDataTableParamModel) As JsonResult
Return GetJson(dataTableParams, Request.Params,
Function(r) New String() {
Convert.ToString(r.Id),
r.Description,
r.Comment})
End Function
这是因为控制器是从T的通用基本控制器派生的.GetJson方法需要Lambda表达式来创建字符串数组。其余的(过滤,排序和分页)是在IQueryable(Of T)的几个扩展方法中完成的。
在某个地方存在一种策略,它包含几个独立于实际类型的特定过滤器实现。这是通过Dynamic Linq实现的,如下所示:
Public Function ApplyFilter(Of T As {IDataObject})(entities As IQueryable(Of T), filterInfo As System.Tuple(Of String, String)) As IQueryable(Of T) Implements ISmartFilter.ApplyFilter
Dim result As IQueryable(Of T) = Nothing
Try
result = entities.Where(If(filterInfo.Item1 = "", True, String.Format("{0}.ToLower().Contains(@0)", filterInfo.Item2)), filterInfo.Item1.ToLower)
Catch
End Try
Return result
End Function
这里发生的是,这个Where扩展创建了一个表达式,基本上表示像" Where(Description.ToLower()。包含(filtertext))"。
但是,我需要调用与UI中设置的filtertype相对应的正确策略。目前,我只是拥有一个上下文类,它保存所有过滤器的实例,并实现一个迭代所有过滤器的方法,检查它决定是否应用此过滤器的条件。
如果我只是知道过滤类型会更容易。:)
所以问题是:
如何将dataTable.columnFilter中的aoColumns数组放入DataTable的参数列表中,以便我可以从上面提到的DataProviderAction方法访问它?
我也不能改变dataTable和/或columnFilter本身的任何代码......
答案 0 :(得分:0)
你们怎么看待这个:
在我的Datatables的jQuery初始化代码中,我添加了一个包含filtertype信息的数组,如下所示:
var filterList = [
{ type: "" },
{ type: "number-range" },
{ type: "text" },
{ type: "text" }
];
然后我定义了一个辅助函数,它创建了几个aodata.push调用,将这些过滤类型注入到我的json字符串中:
fnServerObjectToArray = function () {
return function (sSource, aoData, fnCallback) {
for (i = 0; i < filterList.length; i++) {
aoData.push({ "name": "sFilter_" + i, "value": filterList[i].type });
}
$.getJSON(sSource, aoData, function (json) {
fnCallback(json);
});
}
}
在我的数据表初始化中,我将此函数添加为fnServerData:
var oTable = $('#myDataTable').dataTable({
...
"sAjaxSource": "MyController/DataProviderAction",
"fnServerData": fnServerObjectToArray(),
...
});
而columnFilter本身现在基于上面定义的数组:
oTable.columnFilter({
aoColumns: filterList
});
直到策略,上下文现在保存字典中的可用过滤器:
Private Shared availableFilters As New Dictionary(Of String, ISmartFilter) From {
{"number", New NumberFilter()},
{"number-range", New NumberRangeFilter()},
{"text", New TextFilter()}
}
这样我现在可以用这样的方式应用相应的过滤器:
Public Shared Function ApplyFilter(Of T As {IDataObject})(entities As IQueryable(Of T), filterInfo As System.Tuple(Of String, String, String)) As IQueryable(Of T)
Dim filteredEntities As IQueryable(Of T)
Dim filter As ISmartFilter = Nothing
If (availableFilters.TryGetValue(filterInfo.Item3.ToLower(), filter)) Then
filteredEntities = availableFilters(filterInfo.Item3).ApplyFilter(entities, filterInfo)
Else
' Default-Filter
filteredEntities = availableFilters("text").ApplyFilter(entities, filterInfo)
End If
Return filteredEntities
End Function