DataSourceRequest、DataSourceResult 去操作條件因子
本範例主要示範 serverFiltering、serverSorting 作法,當中會去特別操作 DataSourceRequest 物件實體。
一、Model
Model 的部份為使用北風資料庫的 Product table。
二、Controller
HomeController.cs 的內容為
using Kendo.Mvc;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
private NorthwindEntities db = new NorthwindEntities();
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult GetProducts([DataSourceRequest] DataSourceRequest request)
{
//request 物件可視為從前端傳來的 sort、filter 條件因子
updateARFilter(request.Filters);//去操作 filter 條件因子
updateARSort(request.Sorts);//去操作 sort 條件因子
DataSourceResult result = db.Products.ToDataSourceResult(request);
//將 result 相關數值傳回給前端
ProductView ProductView = new ProductView();
ProductView.Items = (IEnumerable<Product>)result.Data;
ProductView.TotalCount = result.Total;
return JsonNetResult(ProductView);
}
private void updateARFilter(IEnumerable<IFilterDescriptor> iFilters)
{
//如果前端傳單一 Filter 條件進來的話,iFilters 集合裡的型態則為 FilterDescriptor
//如果前端傳複合 Filter 條件進來的話,iFilters 集合裡的型態則為 CompositeFilterDescriptor
//一個 CompositeFilterDescriptor 包含多個 FilterDescriptor
//每次前端頁面發出一個 request 就有可能會同時包含兩個 CompositeFilterDescriptor,
//一個 CompositeFilterDescriptor 為前端 js 已經設定好的條件集合,
//另一個 CompositeFilterDescriptor 為人工點選所設定的條件集合。
foreach (var iFilter in iFilters)
{
if (iFilter is FilterDescriptor)
{
var filter = (FilterDescriptor)iFilter;
//如果有去設定 Discontinued 欄位篩選條件的話,改去篩 UnitPrice 欄位小於 5 的資料出來
if (filter.Member == "Discontinued")
{
filter.Member = "UnitPrice";
filter.Operator = FilterOperator.IsLessThan;
filter.Value = 5;
}
}
else if (iFilter is CompositeFilterDescriptor)
{
updateARFilter(((CompositeFilterDescriptor)iFilter).FilterDescriptors);
}
}
}
private void updateARSort(IList<SortDescriptor> sorts)
{
foreach (var sort in sorts)
{
//如果有去排序 ReorderLevel 欄位的話,則改去排 ProductID 欄由小到大
if (sort.Member == "ReorderLevel")
{
sort.Member = "ProductID";
sort.SortDirection = ListSortDirection.Ascending;
}
}
}
private ContentResult JsonNetResult(object model)
{
return Content(Newtonsoft.Json.JsonConvert.SerializeObject(model), "application/json", System.Text.Encoding.UTF8);
}
}
}
說明:
1、如果前端傳單一 Filter 條件進來的話,iFilters 集合裡的型態則為 FilterDescriptor。
2、如果前端傳複合 Filter 條件進來的話,iFilters 集合裡的型態則為 CompositeFilterDescriptor。
3、一個 CompositeFilterDescriptor 包含多個 FilterDescriptor。
4、sort 的部份,其原理也是跟 filter 大同小異的。
三、View
Index.cshtml 的內容為
@{
ViewBag.Title = "Home Page";
}
<div id="grid"></div>
@section scripts
{
<script src="https://kendo.cdn.telerik.com/2020.1.406/js/kendo.all.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.406/js/kendo.aspnetmvc.min.js"></script>
<script>
$(document).ready(init);
function init() {
var dataSource = new kendo.data.DataSource({
type: 'aspnetmvc-ajax',
transport: {
read: {
datatype: "json",
type: "post",
url: "/Home/GetProducts"
}
},
schema: {
data: 'Items',
total: 'TotalCount'
},
serverPaging: true,
pageSize: 10,
serverFiltering: true,
filter: [
{ field: 'CategoryID', operator: 'eq', value: 1 },
{ field: 'SupplierID', operator: 'lte', value: 15 }
],
serverSorting: true,
sort: {
field: "UnitPrice", dir: "desc"
},
});
$("#grid").kendoGrid({
columns: [
{ field: "ProductID", width: 120 },
{ field: "ProductName", width: 120 },
{ field: "SupplierID", width: 120 },
{ field: "CategoryID", width: 120 },
{ field: "QuantityPerUnit", width: 120 },
{ field: "UnitPrice", width: 120 },
{ field: "UnitsInStock", width: 120 },
{ field: "UnitsOnOrder", width: 120 },
{ field: "ReorderLevel", width: 120 },
{ field: "Discontinued", width: 120 }
],
dataSource: dataSource,
pageable: true,
filterable: true,
sortable: true
});
}
</script>
}
說明:
注意,當你去操作 DataSourceRequest 物件實體裡面的屬性的話,請記得要 include kendo.aspnetmvc.min.js 檔,
並 kendo.data.DataSource 的 type 屬性要設定為 aspnetmvc-ajax,
否則 DataSourceRequest 物件實體裡面的屬性將為 null。
四、FilterDescriptor、SortDescriptor 類別參考
FilterDescriptor 的內容為
namespace Kendo.Mvc
{
public class FilterDescriptor : FilterDescriptorBase
{
public FilterDescriptor();
public FilterDescriptor(string member, FilterOperator filterOperator, object filterValue);
public object ConvertedValue { get; }
public string Member { get; set; }
public Type MemberType { get; set; }
public FilterOperator Operator { get; set; }
public object Value { get; set; }
public virtual bool Equals(FilterDescriptor other);
public override bool Equals(object obj);
public override int GetHashCode();
protected override Expression CreateFilterExpression(ParameterExpression parameterExpression);
protected override void Serialize(IDictionary<string, object> json);
}
}
SortDescriptor 的內容為
namespace Kendo.Mvc
{
public class SortDescriptor : JsonObject, IDescriptor
{
public SortDescriptor();
public SortDescriptor(string member, ListSortDirection order);
public string Member { get; set; }
public ListSortDirection SortDirection { get; set; }
public ClientHandlerDescriptor SortCompare { get; set; }
public void Deserialize(string source);
public string Serialize();
protected override void Serialize(IDictionary<string, object> json);
}
}