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隨筆》目錄:http://www.cnblogs.com/sanshi/p/6473592.html 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM