Kendo UI Grid 模型繫結

2022-09-13 01:57:14 字數 4952 閱讀 4439

接觸 asp.net mvc 時間較長的童鞋可能都會了解過模型繫結(model binding),而且在一些做 web 專案的公司或是team面試中也經常會被問到。專案中有很多 action 中都使用了自定義的模型繫結,但是業務邏輯太過複雜不適合做為例子與大家分享,而今天在做乙個 kendo ui 的功能時覺得可以用 kendo ui 做為例子與大家分享與**乙個典型的 model binding 的過程。

kendo ui:它是乙個非常出名的第三方控制項公司,說直白點就是乙個賣軟體的公司,但主要的目標使用群體是開發人員或是軟體開發公司(包括 web 與 桌面軟體)。kendo ui 主要是針對 web 開發,其 kendo ui 中的各種控制項(widget)能夠提供非常漂亮及友好的使用者介面和使用者體驗,並且提供了大量的介面以方便使用程式設計的方式控制它的控制項以達到特定的需求。

asp.net model binding:當帶有引數的請求(從form表達提交或是拼接在 url 中的 querystring)到達 asp.net mvc 程式後,會被解析成乙個 httprequest 型別的物件並且成為 controllercontext 中的成員變數,如果 debug 時在乙個 action 裡打乙個斷點,然後在即時視窗(immediate window)中執行 this.request.params.allkeys 就會得到此次請求的所有引數鍵名,當然你就可以通過 this.request.params["parameterkey"] 找到任何引數值,所以 model binder 所做的工作就是把這個過程進行了封裝,簡而言之就是由模型繫結器(model binder)來完成 action 引數列表裡 viewmodel 的成員匹配,會使**更加的簡潔處理 viewmodel 繫結時更加的優雅。如果對**有潔癖的人一定會喜歡它的。

這個功能在如下情境下會非常有用:

1. 乙個複雜的頁面需要將很多引數傳遞給後台(action)進行處理,而這些引數可能需要一些計算、驗證進而進行整合生成乙個更加符合業務需求的 view model。這樣的需求在日常開發中應該會有不少,如果統統寫在 action 裡,那**估計都不忍真視。

2. 更加優雅的編寫後台程式。

3. 把面試官侃暈。

將要介紹的 kendo ui 中的 model binding 正好可以實現以上的需求。

kendo ui 中的 datasourcerequestmodelbinder 就是今天的主角兒,我們可能通過 reflector 或是 resharper 得到反編譯後的部分**,從以下**足以了解自定義模型繫結的實現原理。

在 datasourcerequestmodelbinder 類中,可以看出乙個典型的自定義模型繫結器(model binder)需要實現 imodelbinder 介面,其中只有乙個方法,當然就是 bindmodel。而在 bindmodel 方法中也只做了三件事:

從 httprequest.params 找到具體的引數值,由 trygetvalue() 方法中的 bindingcontext.valueprovider.getvalue(key) 完成這個工作(有興趣的童鞋可以使用 resharper 跟進去看看)。

解析這些值(create 或是 deserialize)得到 descriptor。

將這些 descriptor 整合成乙個 datasourcerequest 物件,並返回。

1

public

class

datasourcerequestmodelbinder : imodelbinder24

5public

object

bindmodel(controllercontext controllercontext, modelbindingcontext bindingcontext)628

29private

bool trygetvalue(modelbindingcontext bindingcontext, string key, out

t result)

3039

else

4044

}45 }

1

public

static

class

gridurlparameters24

5public

static

string filter 67

public

static

string page 89

public

static

string pagesize

1011

public

static

string sort

1213

public

static

string group

1415

public

static

string mode

1617

static

gridurlparameters()

1827

28public

static idictionary< string, string> todictionary( string

prefix)

2939 }

kendo grid descriptor 序列化器類:

1

public

class

griddescriptorserializer212

13public

static ilistdeserialize( string

from) where t : idescriptor, new

()14

24return (ilist) list;25}

26 }

需求場景

在了解了以上的背景知識後,我們來設定乙個具體的需求場景:kendo ui grid 控制項中可以在前端頁面中實現 過濾(filter)、分組(group)以及 排序(sort),當然 kendo grid 還有很多酷炫的功能,但今天的主角兒就是以上三位。現在使用者希望在對 grid 中的結果集進行了 filter、group 及 sort 過濾操作後,能將這些操作命令儲存至資料庫中的 userprofile 表中,以便下次同一使用者登入後能還原其過濾後的結果集。

分析

1

public

actionresult filtermenucustomization_read([datasourcerequest] datasourcerequest request)

2

kendo grid 傳送的帶有 filter、sort 以及 group 的 httprequest 都是由 kendo 前端 js 指令碼完成的,所以我們不知道它是如何得到這些資訊的,以及如何能夠讓它同時發乙份到另乙個 actionb 中然後我們在 actionb 中儲存起來。

檢視 js 檔案? 不行的,它的檔案可讀性非常差,是專門處理過的。裡面到處都是 a b c .... 無意義的字元做為變數名,所以除非高人在世。

思路

1. 在 js 中獲取到 grid 的過濾條件。

2. 使用 $.ajax() 把這些條件post 至 home/storegridcommans 中。

整個實現過程很簡單,在這裡簡單描述下:

1. $("#gridelementid").data("kendogrid") 拿到 kendoobject,在 kendoobject.datasource 中即有我們需要的所有過濾條件,如 kendoobject.datasource._filter,kendoobject.datasource._sort,kendoobject.datasource._group。

2. 通過觀察 grid 的一次資料請求過程,即可了解 kendo 前端 js 會將過濾條件做怎樣的處理後提交到後台,最終發現以如下形式傳遞這些過濾條件:

&sort=fieldname1-aes&filter=fieldname2~eq~and~fieldname3~neq&group=fieldname4-aes

3. 將 1 步中得到的過濾條件按第 2 步中的格式進行拼接並做為引數傳遞給 storegridcommands action 中,可以直接放在 url 中做為 querystring,也可以封裝進成乙個 json 物件傳遞。

需要留心的小問題

這裡有一點需要注意的是對 datetime 型別的列的處理會稍有不同。kendo grid 接收到的都是經過 json 序列化後的值 形如:「/date(12345678)/」,這個值在它接收到後會做解析,但解析出的值會帶有瀏覽器的本地時區 即:mon 20 2014 13:12:00 (中國時間),而且在 kendoobject.datasource._filter 中拿到值也是如此,而這個值在進行 modelbinding 時是會出錯的,modelbinder 中對於時間型別的處理會以如下形式解析:

1

private

static datetime parsedatetime(string

value)

2

所以我們需要在處理過濾條件時特別留心 datetime型別的列及其值,在 kendo grid 載入後在前端可以使用 kendo.format() 來對時間型別的資料值進行格式化。     

1

var filtercondition = "";23

var filterdata =kendoobject.datasource._filter;45

if(filterdata !=undefined)15}

16 }

注:filterdata.logic 在迴圈中是需要判斷下是否要新增,如果有多個 filter 就新增該 logic,沒有的話就不加。**很簡單,如果有這方面需要的童鞋可以自己嘗試寫寫。

MVC模型繫結

一 理解模型繫結 模型繫結是http請求與c 方法之間的乙個橋梁,它根據 action 方法中的 model 型別建立 net 物件,並將 http 請求資料經過轉換賦給該物件。二 預設的模型繫結器 應用程式有多個繫結器,大多數的都是依賴與內建繫結器類 defaultmodelbinder,一般情況...

MVC 模型繫結

在webform,獲取提交表單的值一般都是request.form title 這樣的方式。在mvc中,提供了模型繫結機制。讓後台獲取表單或url中的引數變得更加簡單。你可以直接在引數中用字串,整型變數,實體或者是list 實體 的方式獲取表單提交的引數。引數中的這些東西都是與表單中的html控制項...

關於 KendoUI Grid的預設選中的一些事

kendoui grid的資料集是在 data下面,獲取資料可以直接使用grid 資料集 data 是要預設選中那一條資料,id 選中具體資料 var grid user table data kendogrid user table是資料集 var id grid.data 0 id 預設選中我第...