检索jQuery DataTable的ColumnFilter插件的过滤类型

时间:2012-09-24 13:34:56

标签: jquery asp.net-mvc model-view-controller datatable

我正在使用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本身的任何代码......

1 个答案:

答案 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