FineUIMvc隨筆(6)對比WebForms和MVC中表格的資料庫分頁
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。
通過對比WebForms和MVC中表格資料庫分頁程式碼的不同,可以對 MVC 中的資料流轉有更加深入的瞭解。
WebForms 中表格的資料庫分頁
WebForms中的程式碼會比較直觀,我們從具體是示例入手:
http://fineui.com/demo/#/demo/grid/grid_paging_database.aspx
前臺標籤定義,簡單起見省略了部分列定義:
<f:Grid ID="Grid1" Title="表格" EnableCollapse="true" Width="800px" PageSize="5" ShowBorder="true" ShowHeader="true" AllowPaging="true" runat="server" EnableCheckBoxSelect="True" ShowPagingMessage="false" DataKeyNames="Id,Name" IsDatabasePaging="true" OnPageIndexChange="Grid1_PageIndexChange"> <Columns> <f:RowNumberField /> <f:BoundField Width="100px" DataField="Name" DataFormatString="{0}" HeaderText="姓名" /> ..... </Columns> </f:Grid>
為了啟用資料庫分頁,我們需要定義如下屬性:
1. AllowPaging=true:啟用分頁
2. IsDatabasePaging=true:啟用資料庫分頁
3. PageSize=5:每頁記錄數
4. OnPageIndexChange=Grid1_PageIndexChange:分頁切換事件,需要回發到後臺重新繫結表格資料
後臺的初始化程式碼:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindGrid(); } } private void BindGrid() { // 1.設定總項數(特別注意:資料庫分頁一定要設定總記錄數RecordCount) Grid1.RecordCount = GetTotalCount(); // 2.獲取當前分頁資料 DataTable table = GetPagedDataTable(Grid1.PageIndex, Grid1.PageSize); // 3.繫結到Grid Grid1.DataSource = table; Grid1.DataBind(); }
資料繫結時執行了三個操作:
1. 設定表格總記錄數,在資料庫分頁時這個是必須要的
2. 獲取當前分頁資料,傳入當前頁序號(預設為PageIndex=0)以及每頁顯示記錄數
3. 將資料繫結到表格
後臺的分頁事件處理函式:
protected void Grid1_PageIndexChange(object sender, GridPageEventArgs e) { BindGrid(); }
分頁回發事件中,表格會自動記錄當前頁序號,所以這裡只需要簡單的呼叫 BindGrid 函式即可!程式碼簡單,一氣呵成!
在 MVC 中就沒那麼容易的了。
MVC 中表格的資料庫分頁
我們來看具體的示例:http://fineui.com/demo_mvc#/demo_mvc/GridPaging/Database
首先看下前臺 View 的定義:
@(F.Grid() .EnableCheckBoxSelect(true) .Width(850) .ShowHeader(true) .ShowBorder(true) .EnableCollapse(true) .Title("表格") .ID("Grid1") .DataIDField("Id") .DataTextField("Name") .AllowPaging(true) .PageSize(5) .IsDatabasePaging(true) .OnPageIndexChanged(Url.Action("Grid1_PageIndexChanged"), "Grid1") .Columns( F.RowNumberField(), F.RenderField() .HeaderText("姓名") .DataField("Name") .Width(80), ...... ) .RecordCount(ViewBag.Grid1RecordCount) .DataSource(ViewBag.Grid1DataSource) )
和 WebForms 中的類似,我們同樣需要設定一些屬性來啟用資料庫分頁:
1. AllowPaging(true):啟用分頁
2. IsDatabasePaging(true):啟用資料庫分頁
3. PageSize(5):每頁記錄數
4. OnPageIndexChanged(Url.Action("Grid1_PageIndexChanged"), "Grid1"):分頁切換事件,需要回發到後臺重新繫結表格資料
注意 OnPageIndexChanged 事件處理函式的定義,它比 WebForms 中多了個引數 Grid1,在前面文章中我們知道這個引數會把表格的相關分頁排序等資訊一起回發到後臺。
為什麼WebForms不需要這些資訊呢?
因為 WebForms 通過 ViewState 等內部機制來維持 HTTP 請求之間控制元件的狀態,從而可以方便的在後臺使用 Grid1.PageIndex 等屬性。
除了上面的四個屬性,你可能還注意到如下兩個設定:
5. RecordCount(ViewBag.Grid1RecordCount)
6. DataSource(ViewBag.Grid1DataSource)
這兩個是通過 ViewBag 從控制器傳入的引數,分別對應於表格總記錄數和當前分頁資料來源。對比下 WebForms 中實現,我們可以清楚的意識到:
1. WebForms中頁面初始化時,後臺程式碼能夠直接訪問到頁面(.aspx)上定義的控制元件,所以可以直接在後臺程式碼中對控制元件賦值。
2. MVC中頁面初始化時,後臺程式碼不能訪問到檢視(.cshtml)上定義的控制元件,所以必須在控制器方法中準備好資料,然後傳入檢視中。
看下頁面初始化時,MVC如何準備表格分頁資料,並存儲到 ViewBag 中:
// GET: GridPaging/Database public ActionResult Index() { LoadData(); return View(); } private void LoadData() { var recordCount = DataSourceUtil.GetTotalCount(); // 1.設定總項數(特別注意:資料庫分頁初始化時,一定要設定總記錄數RecordCount) ViewBag.Grid1RecordCount = recordCount; // 2.獲取當前分頁資料 ViewBag.Grid1DataSource = DataSourceUtil.GetPagedDataTable(pageIndex: 0, pageSize: 5, recordCount: recordCount); }
正因為如此,在MVC中,頁面初始化和之後的事件處理函式(回發)不能共用 BindGrid 類似的函式。
因此,在分頁切換事件處理函式中(換成MVC的術語:客戶端的分頁事件對應的後臺控制器方法),我們需要通過 UIHelper 幫助來更新表格資料:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Grid1_PageIndexChanged(JArray Grid1_fields, int Grid1_pageIndex) { var grid1 = UIHelper.Grid("Grid1"); var recordCount = DataSourceUtil.GetTotalCount(); // 1.設定總項數(資料庫分頁回發時,如果總記錄數不變,可以不設定RecordCount) grid1.RecordCount(recordCount); // 2.獲取當前分頁資料 var dataSource = DataSourceUtil.GetPagedDataTable(pageIndex: Grid1_pageIndex, pageSize: 5, recordCount: recordCount); grid1.DataSource(dataSource, Grid1_fields); return UIHelper.Result(); }
注意,控制器方法的兩個引數名稱是約定好的,如果前臺通過控制元件ID的方式來傳入自定義回發引數時:
OnPageIndexChanged(Url.Action("Grid1_PageIndexChanged"), "Grid1")
後臺接受請求的引數名約定為:
1. 表格控制元件ID_pageIndex:表格當前分頁序號
2. 表格控制元件ID_fields:表格用到了哪些表格欄位(如果不是表格,是IEnumrable<Class>物件,則對應於類屬性列表),這個值在資料繫結時需要用到。
為什麼需要 Grid1_fields 引數?
很多網友會有這個疑問,其實理解起來也很簡單。因為表格可能存在很多欄位,假設有 100 個,可能只有其中的 10 個欄位表格用到了。那麼資料繫結時只返回這 10 個欄位的資料。
假設資料繫結時沒有傳入這個引數,也是可以執行的,只不過會返回很多冗餘資料,也可能會造成關鍵資料洩密(比如密碼等)。
最後,我們看下 MVC 中,分頁回發的請求正文:
響應正文:
F.ui.Grid1.setRecordCount(22); F.ui.Grid1.loadData([ [106, "張博", 1, 2003, true, "財務管理", 3, "2017-01-13T07:22:51Z"], [107, "楊倩倩", 0, 2000, false, "材料物理與化學", 4, "2017-01-23T07:22:51Z"], [108, "董超", 1, 2004, false, "生物醫學工程", 4, "2017-02-02T07:22:51Z"], [109, "張娟娟", 0, 2003, true, "材料物理與化學", 5, "2017-02-12T07:22:51Z"], [110, "葉鵬", 1, 2006, false, "電子商務", 5, "2017-02-22T07:22:51Z"] ]); F.ui.Grid1.clearSelection();
小結
學習 FineUIMvc 中表格的資料庫分頁程式碼,關鍵是要理解 WebForms 和 MVC 的不同工作方式。
WebForms中頁面初始化時,後臺程式碼可以直接訪問頁面控制元件,所以能直接在後臺程式碼中對控制元件進行資料繫結。MVC中頁面初始化時,控制器方法中不能訪問檢視中定義的控制元件,需要準備資料通過ViewBag或者模型物件傳入到檢視中。
WebForms中頁面回發時,後臺程式碼可以知道控制元件的所有屬性。MVC中頁面回發時,後臺程式碼需要的任何引數都要由前臺通過JavaScript程式碼顯式的傳入(FineUIMvc提供了控制元件ID作為引數的簡單傳值方法)。
相關推薦
FineUIMvc隨筆(6)對比WebForms和MVC中表格的資料庫分頁
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 通過對比WebForms和MVC中表格資料庫分頁程式碼的不同,可以對 MVC 中的資料流轉有更加深入的瞭解。 WebForms 中表格的資料庫分頁 WebForms中的程式碼會比較直觀,我們從具體是示例入手: http://fin
FineUIMvc隨筆(2)怎樣在控制元件中巢狀 HTML
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 使用者需求 有網友在《FineUI總群1》問這麼一個問題:怎麼把 HTML 巢狀在控制元件中? 這是很多剛學習 FineUIMvc 的網友經常問的問題,我想原因是對 WebForms 陷入太深,習慣了 FineUI 控制
學習用Node.js和Elasticsearch構建搜索引擎(6):實際項目中常用命令使用記錄
nds 黃色 ati cat htm action last shard open 1、檢測集群是否健康。 curl -XGET ‘localhost:9200/_cat/health?v‘#後面加一個v表示讓輸出內容表格顯示表頭 綠色表示一切正常,黃色表示所有
(6)typeof, null, 和 undefined
ava 對象 defined 一個 返回 script eof bsp 引用 typeof 操作符 可以用於檢測變量的數據類型 Null 在 JavaScript 中 null 表示 "什麽都沒有"。 null是一個只有一個值的特殊類型。表示一個空對象引用。 可以設置為 n
flink流計算隨筆(6)
starting nts 取消 add multi nvi handle input .sh ?生成,編譯模板工程 MacBook-Air:SocketWindowWordCount myhaspl$ bash <(curl https://flink.apache.
(二)對比Exception和Error,執行時異常與一般異常的區別
Excpetion和Error都是繼承了Throwable,在java中只有Throwable型別的例項才能丟擲throw或者捕獲catch,它是異常處理機制的基本組成型別。 Exception:是程式正常執行情況下,可以預料的意外情況,可以並且應該被捕獲,進行
阿里雲隨筆(6)
列出oss桶下所有的csv檔案: import tensorflow as tf FLAGS = tf.flags.FLAGS tf.flags.DEFINE_string('buckets', 'os
C++學習筆記(6)——C++運算子和表示式
C++程式是由各式各樣的語句組成的,而語句又是由表示式轉化而來的。C++表示式是任何值或任何有效值與運算子的組合。本篇筆記總結C++程式的基本構成元素之一——表示式以及構成它所需的運算子。 一、表示式 需要明確任何值或任何有效值與運算子的組合都是表示式。同理,每個表示式都
ZooKeeper場景實踐:(6)叢集監控和Master選舉
1. 叢集機器監控 這通常用於那種對叢集中機器狀態,機器線上率有較高要求的場景,能夠快速對叢集中機器變化作出響應。這樣的場景中,往往有一個監控系統,實時檢測叢集機器是否存活。 利用ZooKeeper有兩個特性(讀可監控,臨時節點),就可以實現一種叢集機器存活性監控系統: 1. 客戶端在節點 x 上註冊
Django系列教程(6)-- HttpRequest物件和HttpResponse物件
HttpRequest物件 伺服器接收到http協議的請求後,會根據報文建立HttpRequest物件,然後將其傳遞給檢視函式 屬性 下列屬性中,除特殊說明都是隻讀的 path:一個字串,表示請求頁面的完整路徑,不包含域名 method:一個字串,表
Facebook React 和 Web Components(Polymer)對比優勢和劣勢
譯者前言 這是一篇來自 StackOverflow 的問答,提問的人認為 React 相比 WebComponents 有一些“先天不足”之處,列舉如下: 原生瀏覽器支援 原生語法支援(意即不把樣式和結構混雜在 JS 中) 使用 Shado
FineUIMvc隨筆(1)動態建立表格列
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 《FineUIMvc隨筆》目錄 ... 使用者需求 使用者希望實現動態建立表格列,在 WebForms 中,我們通過在 Page_Init 中建立列來實現: 但
FineUIMvc隨筆(7)擴充套件通知對話方塊(顯示多個不重疊)
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 這篇文章我們將改造 FineUIMvc 預設的通知對話方塊,使得同時顯示多個也不會重疊。並提前出一個公共的JS檔案,供大家使用。 FineUIMvc 的通知對話方塊 FineUIMvc預設的通知對話方塊通過 F.notify 來顯示
FineUIMvc隨筆(4)自定義回發引數與自定義回發
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 不能忘卻的回發 在上一篇文章中,我們對FineUIMvc中的回發進行了詳細描述,目的是為了告訴大家: 1. FineUIMvc中的回發其實是請求控制器方法的另一種表述而已 2. 回發是輕量級,只會傳入你允許傳入的引數 3. 回發
FineUIMvc隨筆(5)UIHelper是個什麼梗?
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 UIHelper.Result 在 FineUIMvc 的每一個 HttpPost 的控制器方法裡面,你都會看到 UIHelper.Result(): 這到底是個什麼梗?在 ASP.NET MVC 中並沒有 UIHelper
FineUIMvc隨筆(3)不能忘卻的回發(__doPostBack)
宣告:FineUIMvc(基礎版)是免費軟體,本系列文章適用於基礎版。 使用者反饋 有網友在官方論壇丟擲了這麼一個問題,似乎對 FineUIMvc 中的瀏覽器端與伺服器端的互動方式很有異議。 這裡面的關鍵詞就是:回發! 似乎一提到回發(__doPostBack),就讓人聯想到 Web
像MIUI一樣做Zabbix二次開發(6)——應用場景和規劃
其他使用場景 監控做為一個重要的管理手段,存在很多的使用場景,簡單列舉我們現在碰到的: 1. 系統整合 事件管理流程整合;配置管理整合,自動CI獲取,提高CMDB準確、實時性;知識庫整合,提高知識庫的可持續消費能力 2. 物聯網裝置監控 物聯網裝
C語言詳解(6)巨集定義和條件編譯
巨集定義和條件編譯 一、概述 巨集定義是C語言的預處理功能。巨集定義就是簡單的替換,不作為計算,不也作為表示式。在C語言中作為預處理指令包括:巨集定義、檔案包含、條件編譯。 條件編譯其實就是將if…else…的設計思想引入到預處理功能中,給編譯器使用的。條件編譯時通過
機器學習筆記(6)——C4.5決策樹中的剪枝處理和Python實現
1. 為什麼要剪枝 還記得決策樹的構造過程嗎?為了儘可能正確分類訓練樣本,節點的劃分過程會不斷重複直到不能再分,這樣就可能對訓練樣本學習的“太好”了,把訓練樣本的一些特點當做所有資料都具有的一般性質,cong從而導致過擬合。這時就可以通過剪枝處理去掉yi一些分支來降低過擬合
Java NIO(6):Server和Client案例
Server:package com.tony.app; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio