2011年8月25日 星期四

菜鳥上路‧ 運用ASP MVC2 編寫資料分頁顯示(一)

安安!! 今日來再和大家一起學習ASP.net mvc2 吧!!
對於網頁程式員來說,懂得編寫分頁顯示資料是必要的事,試想想如果只用一頁網頁顯示幾千筆資料記錄,用戶看後不殺了你才怪!! 現在各大型網站都以分頁顯示資料的,懂得如何編寫分頁顯示資料就有基礎能力改良網頁的排版,明白了我們就馬上開始學習吧!!

以往有學ASP.net的朋友,會知道以往ASP.net是用GridView或DataGrid物件來作分頁顯示資料,並且十分簡單地用selectCommand方式把資料庫的資料提供GridView或DataGrid,無論你的程式碼如何不同,都是可以依相應的程式碼選GridView或DataGrid作分頁物件顯示。可是,到了MVC2,我發現是不能用GridView或DataGrid了(可能是我知識不足),要做到分頁顯示資料,我只想到兩個方法:

1. 用for loop 迴圈逐筆顯示資料,再自編寫分頁程式碼(舊式方法)
2. 用jquery或第三方的軟件等所提供的DataGrid物件作分頁顯示(有些可能要錢買)

但我今次要講的當然是前者!因為我覺得前者比較難,畢竟全部程式碼都是自己寫,當理解後再學後者較容易。
這次我所用的開發工具是Microsoft Visual Web Developer 2008 Express Edition, .NET framework 3.5 sp1, Microsoft SQL Server 2008 Express Edition。至於MVC2的資料庫連結方式最常採用是將LINQ轉化成資料表物件。在這次所涉及的新增和修改檔案包括Index.aspx、HomeController.vb和DataClasses1.dbml,如下圖:


  • Index.aspx內的程序碼是屬於顯示分頁資料於用戶介面。
  • HomeController.vb內的程序碼是用來查詢資料庫以供資料記錄給Index.aspx。
  • DataClasses1.dbml則是以LINQ to Classes方式所產生的資料庫物件,透過linq語法被利用來查詢資料庫內的資料。
  • 開始請先新增一個專案名為test,如下圖:

    接著在右面的Solution Explorer視窗中指向專案名test,然後按滑鼠右鍵,選Add -> New Item,如下圖:

    這時Add New Item出現視窗,請在左面Catagories選取Data,再在右面Templates選擇LINQ to SQL Classes,並改dbml名稱為DataClasses1.dbml,然後按Add按鈕,如下圖:

     這樣,DataClasses1.dbml檔案產生了(這個檔就是用作儲存資料表物件)

    跟著就是把Solution Explorer視窗轉到Database Explorer視窗,然後在Database Explorer視窗中新增一條資料庫連接MSSQL伺服器內的資料庫。在範例中我有一個資料庫名為PCInventory,內有幾個資料表,而我在範例中只用的資料表叫ITStock,其內容是一些電腦器材的資料包括有三個欄位分別是序號、產品描述和狀態,請把ITStock從Database Explorer視窗拖到DataClasses1.dbml的檔案內,如下圖:

    接著DataClasses1.dbml便可透過LINQ的查詢語法所使用了,請把Database Explorer視窗轉回Solution Explorer視窗,然後在Solution Explorer視窗中指向Controllers ->HomeController.vb並按下編輯,再貼上下面的程序碼,如下: 


       1:  <HandleError()>
       2:  Public Class HomeController   
       3:   Inherits System_Web_Mvc_Controller   
       4:   
       5:   Function Index() As ActionResult   
       6:   
       7:     Dim dataContext As New DataClasses1DataContext
       8:   
       9:     Dim ItemsPerPage As Integer = 10 '列出一頁包含多少筆記錄
      10:   
      11:     Dim currentPagelndex As Integer = 1 '現在要顯示的頁數
      12:   
      13:     Dim Model = (From m In dataContext.ITStocks Order By m.SerialNum Select m)
      14:   
      15:     Return View(Model.Skip((currentPageIndex - 1) * ItemsPerPage).Take(ItemsPerPage).ToList()) 
      16:   
      17:   End Function  
      18:   
      19:  End Class


    現在我會將程序碼逐一解釋,先來看看第一句:
    Dim dataContext as New DataClasses1DataContext

    以上的意思是把先前產生的DataClasses1.dbml檔透過宣告成為一個DataContext物件供往後編寫LINQ語法時所使用(之於如何用我會在往後再解釋)。而我給該DataContext物件的名稱同樣叫dataContext,舉例來說:若我的dbml檔名叫Sample.dbml,該物件便叫SampleDataContext。而範例dbml檔叫DataClasses1.dbml,故此該物件便叫DataClasses1DataContext。

    接著ItemsPerPage和currentPageIndex這兩個整數變數亦是供LINQ語法所用,之於如何用我會在往後解釋。在編寫分頁顯示資料於介面上,你必須知道究竟一頁要有多少筆記錄,而目前介面是顯示第幾頁等資料才能正常把記錄顯示於對應的頁數,因此範例中ItemsPerPage的數值是10,指在每一頁只顯示十筆記錄,而currentPageIndex的數值是1,則指目前的顯示頁數為第一頁,因為用戶開始進入網頁時必然是以第一頁顯示,當他們按下頁數的超連結才進入其他頁數的介面。
    好了,現在可以用以下LINQ查詢語法解釋如何用DataContext物件了。

    Dim Model = (From m In dataContext.ITSTocks Order By m.SerialNum Select m)

    還記得我之前說過DataClasses1.dbml的檔案內只用的資料表叫ITStock嗎? 由於我已宣告了名為dataContext的DataContext物件,因此現在可透過dataContext來查詢ITStock資料表,在以上的LINQ意思就是透過dataContext來查詢ITStock資料表,再將ITStock資料表依序號欄位順序排列並放入到m中,最後再儲存於Model中。這時Model已有了ITStock資料表的所有記錄。再來便是要把資料表內的所有記錄過濾成先前的所說的只有第一頁的十筆記錄才可提供給Index.aspx作為資料顯示於介面,以下這句的目的便是要做到這點。

    Return View( Model.Skip(( currentPageIndex-1 ) * ItemsPerPage).Take(ItemsPerPage).ToList() )

    Model的.Skip方法是要把原先的Model內的ITStocks資料表中的前端多筆記錄過濾掉,舉例來說:假如ITStocks資料表中存在45筆記錄,而我們目前要顯示第二頁的十筆記錄,則.Skip方法會把第一頁的十筆記錄過濾掉,只剩下由第11筆至第45筆的記錄(共35筆記錄)。然後再以.Take方法拿取由第11筆至第20筆的記錄(共10筆記錄)。請看下圖方便理解:



    但是目前由於currentPageIndex的數值是1,故此.Skip方法不會去掉1至10筆的記錄,結果是只會拿1至10共十筆的記錄作傳回給Index.aspx使用。好了,現在要編輯Index.aspx,Asp.net MVC2是使用Model物件透過for loop 迴圈把剛才由HomeController.vb傳回的十筆記錄逐筆顯示出用戶介面,而所顯示的欄位分別是序號、產品描述和狀態,程式碼如下:


       1:  <%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
       2:   
       3:  <asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server> Home Page </asp:Content>
       4:  <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server"
       5:    &lt;p
       6:    &lt;table>
       7:    <tr>
       8:    <th>序號</th>
       9:    <th>產品描述</th>
      10:    <th>狀態</th>
      11:    </tr>
      12:   
      13:      <% For Each item In Model%>
      14:      <tr>
      15:       <td>
      16:        <%=Html.Encode(item.SerialNum)%>
      17:      </td>
      18:       <td>
      19:        <%=Html.Encode(item.Description)%>
      20:      </td>
      21:       <td>
      22:        <%=Html.Encode(item.Status)%>
      23:      </td>
      24:      </tr>
      25:      <% Next%>
      26:    </table>
      27:   
      28:    </p>
      29:   
      30:  </asp:Content>


    現在可以先看看網頁執行的結果,如下圖:

    下回再繼續...

沒有留言:

張貼留言