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 で設定された filtertype に対応する正しい戦略を呼び出す必要があります。現時点では、すべてのフィルターのインスタンスを保持し、すべてのフィルターを反復処理して、このフィルターを適用するかどうかを決定する条件をチェックするメソッドを実装するコンテキスト クラスしかありません。

フィルタータイプを知っていれば簡単です。:)

質問は次のとおりです。

上記の DataProviderAction メソッドからアクセスできるように、dataTable.columnFilter の aoColumns 配列を DataTable のパラメーター リストに入れるにはどうすればよいですか?

また、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 に答える