0

我正在使用 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().Contains(filtertext))”。

但是,我需要调用与 UI 中设置的过滤器类型相对应的正确策略。目前,我只是有一个上下文类,它包含所有过滤器的实例并实现一个迭代所有过滤器的方法,检查它决定是否应用此过滤器的条件。

如果我只知道过滤器类型会更容易。:)

所以问题是:

如何将 dataTable.columnFilter 中的 aoColumns 数组放入 DataTable 的参数列表中,以便可以从上面提到的 DataProviderAction 方法访问它?

我也不得更改 dataTable 和/或 columnFilter 本身的任何代码......

4

1 回答 1

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
于 2012-09-24T15:14:22.513 回答