這篇文章主要介紹了ASP中實現分頁顯示的七種方法,這七種方法可以分為四大類,需要的朋友可以參考下
在微軟的ASP編程體系中,ADO對象的建立,使得從網頁訪問數據庫成為一件易事,特別是ADO的Recordset對象使得控制數據的輸出顯示更為方便、自由。而在Visual InterDev6.0(以下簡稱VI6.0)中,由於Script Object Model(以下簡稱SOM)、Design-Time Control(以下簡稱DTC)以及Data Environment Object Model(以下簡稱DEOM)等對像模型的引入,使網頁對數據庫的訪問設計顯得更為方便。
因為主題方面的原因,關於數據庫的連接,下文只給出代碼和簡要註釋,而把重點放在如何利用Recordset對象(或控件)實現數據記錄的分頁顯示方面。根據我的理解,分頁顯示的關鍵就在於對ADO的Recordset對像或DTC(設計時控件)的Recordset控件的屬性和方法的熟練把握上。
這七種分頁顯示的武器概括起來說分四類: 第一、二種我暫取名叫純ASP法,
這也是國內的ASP網站上用得最多的方法,它們的區別僅在實現技巧的不同。這兩種方法的實現最易理解,用到的對象概念也最少,對開發環境的要求也最低(只要記事本就行)。可以說,這兩種方法的實質還是CGI的編程思想,只是在程序中引入了ADO對象而已。
第四、五種暫取名叫SOM的DHTML法。
這兩種方法要求在VI6.0的環境下,利用微軟提出的腳本對像模型(Script Object Model)和DHTML中Table對象的與數據庫綁定的新特性(許多書和文章只介紹了DHTML的CSS特性在樣式設計中的運用而忽略介紹其數據綁定特性),實現在客戶端控制翻頁。但它要求用戶的瀏覽器必須是支持DHTML,如:Microsoft Internet Explorer 4.0及以上的版本。
第六種暫取名叫SOM服務器端法。
要求在VI6.0的環境下開發,它利用微軟提出的腳本對像模型(Script Object Model)中的幾個DTC控件:Recordset、PageObject、Grid等在服務器端(客戶端)實現翻頁控制。這是一種激動人心的、全新的編程方法,它把網頁看成對象(這種對像模型和傳統的DOM----document object model是有區別的:DOM只能控制客戶端,而SOM可控制服務器端和客戶端),它真正實現了網頁的面向對象編程。但遺憾的是,也許是我個人能力有限,這種技術我個人認為還不是很成熟,比如,與瀏覽器的結合還不是很好,這將在後文詳細說明。
第七種暫取名叫DEOM法。
它也是利用了VI6.0中建立的數據環境對像模型(Data Environment Object Model)建立Recordset對象。這也是在網頁編程上比較少見的新方法,與SOM模型相比,自有它的優點,這將在後文詳述。
在後面所舉的所有例子源代碼,都可以直接拷貝使用,你甚至可以不懂其原理,只要把其中的粗斜體字部分換成相應自己的數據庫名或字段名就可以了。
在開始詳細介紹各種分頁方法前,讓我們先創建一個數據庫:用Office97中的access自創一個Employee.mdb,其中建一個表emp,只設三個字段:emp ID,last name和first name。為什麼這麼簡單,是因為我們關心的是怎樣處理recordset的結果。
第一種:參數直接代入法
這種方法是用手工建立Recordset對象,利用其pagesize(每頁指定顯示記錄數),pagecount(總頁碼數)和absolutepage(當前頁碼數)屬性來控制分頁的輸出。分頁採用直接帶頁碼參數的方法來控制翻頁。網頁的名字為emp1.asp。源代碼如下:
- <%//建立與employee.mdb數據庫的連接。
- Setconn=Server.CreateObject(ADODB.Connection)
- conn.Opendriver={MicrosoftAccessDriver(*.mdb)};dbq=employee.mdb
- //建立emp表的Recordset對象實例rs。
- Setrs=Server.CreateObject(ADODB.Recordset)
- rs.Openemp,conn,3
- PageSize=10//pagesize屬性指定了每頁要顯示的記錄條數
- Page=CLng(Request(Page))'string型轉化為long型
- IfPage<1ThenPage=1
- IfPage>rs.PageCountThenPage=rs.PageCount
- IfPage<>1Then
- Response.Write<AHREF=emp1.asp?Page=1>第一頁</A>
- Response.Write<AHREF=emp1.asp?Page=&(Page-1)&>上一頁</A>
- EndIf
- IfPage<>rs.PageCountThen
- Response.Write<AHREF=emp1.asp?Page=&(Page+1)&>下一頁</A>
- Response.Write<AHREF=emp1.asp?Page=&rs.PageCount&>最後一頁</A>
- EndIf
- Response.write頁碼:&Page&/&rs.PageCount&</font>
- //每一頁的顯示
- //顯示表頭
- Response.Write<CENTER><TABLEBORDER=1>
- Response.WRITE<TR><TD>&rs.Fields(empID).Name&</TD>
- Response.WRITE<TD>&rs.Fields(lastname).Name&</TD>
- Response.WRITE<TD>&rs.Fields(firstname).Name&</TD></TR>
- //循環顯示每條記錄
- rs.AbsolutePage=Page//把頁碼賦給absolutepage屬性從而知當前頁的首條記錄號
- ForiPage=1Tors.PageSize//
- Response.WRITE<TR><TD>&rs.Fields(empID).Value&</TD>
- Response.WRITE<TD>&rs.Fields(firstname).Value&</TD>
- Response.WRITE<TD>&rs.Fields(lastname).Value&</TD></TR>
- rs.MoveNext
- Ifrs.EOFThenExitFor
- Next
- Response.Write</TABLE></CENTER>%>
第二種:表單傳送參數法
這種方法在創建Recordset對象時與第一種相同,只是在翻頁控制時,採用和case語句配合來實現翻頁。網頁的名字為:emp2.asp。此方法在編程邏輯上有個缺點:就是在按過上頁或下頁鈕後,再在瀏覽器上按刷新按鈕時,會自動翻頁。源代碼如下:
- ifPagenum=ThenPagenum=1//從第一頁開始顯示
- //建立數據庫連接和Recordset對象實例rs。
- 與第一種方法相同,此處略過。
- RS.Pagesize=10'設置一頁中顯示的記錄條數為10條
- //確定翻頁的動作
- SelectCaseRequest(NAV)
- Case
- session(Pagenum)=1
- caseFirst'FirstRecord
- session(Pagenum)=1
- casePrev'PreviousRecord
- ifsession(Pagenum)>1then
- session(Pagenum)=session(Pagenum)-1
- EndIf
- caseNext'NextRecord
- ifsession(Pagenum)<RS.PageCountthen
- session(Pagenum)=session(Pagenum)+1
- Endif
- caseLast'LastRecord
- session(Pagenum)=RS.PageCount
- EndSelect
- RS.Absolutepage=Clng(session(Pagenum))//確定當前頁的第一條記錄號
- //顯示當前頁
- 同第一種方法,此處略過。
- //Nav翻頁按鈕設置
- <formmethod=GETaction=emp2.asp>
- <inputtype=submitname=NAVValue=首頁>
- <inputtype=submitvalue=上頁name=NAV>
- <inputtype=submitvalue=下頁name=NAV>
- <inputtype=submitvalue=末頁name=NAV></form>
第三種:用Grid控件設計分頁
所有的方法中,這種方法最容易。你只需拖DTC中的Recordset控件和Grid控件到asp網頁中就行了。而且,你還能選擇是在服務器平台還是在客戶端平台控制翻頁。缺點就是你必須用它給定的格式顯示,而不能自己自由控製表格的顯示格式。
方法如下:
在VI6.0中建一個工程emp.vip。再在工程中添加一個asp網頁:emp3.asp。
第一步:選VI6.0菜單條上的add data connect…,按開發工具的導航提示,你就可以很容易地建立與Employee.mdb數據庫的連接。從DTC工具欄中拖一個Recordset控件到網頁中,並設置其屬性。具體如圖:
當你拖控件到網頁中時,VI6.0會自動提示你是否使用Scripting object model,按yes。
第三步:從DTC工具欄中拖一個Grid控件到網頁中,然後單擊鼠標右鍵,設置其屬性,如:選在第二步中創建的Recordset控件名,選擇emp表中的字段,每頁顯示多少條記錄以及顯示格式等。非常簡單方便,只要照著導航提示做就行了。
第四種:DHTML法一。
數據記錄顯示在一個HTML表中。它利用DHTML中表的數據綁定特性來控制記錄的分頁顯示。缺點就是你的翻頁方法將被限制為一種特定的方式:只能上頁和下頁而不能首頁和末頁。由於是在客戶端控制翻頁,所以,這種和第五種方法是速度最快的,但遺憾的是它只能在支持DHTML的瀏覽器上使用。
在DHTML中,
的DATASRC屬性可使表格綁定到一個數據源,另一個屬性DATAPAGESIZE可指定一頁一次顯示的記錄數。
我們來看下面的例子:
第一步:拖Recordset控件到新建的網頁emp4.htm中,設置其屬性,方法同第三種,此處略。
第二步:輸入下面的代碼:
- <TABLEID=Table1DATASRC=#Recordset1_RDSDATAPAGESIZE=5>//假定前面設定Recordset控件名為Recordset1。每頁顯示5條記錄。
- <THEAD>
- <THALIGN=leftWIDTH=150>EmpID</TH>//輸出表頭
- <THALIGN=leftWIDTH=200>LastName</TH>
- <THALIGN=leftWIDTH=200>FirstName</TH>
- </THEAD>
- <TR>
- <TD><DIVDATAFLD=EmpID></DIV></TD>//輸出表內容
- <TD><DIVDATAFLD=LastName></DIV></TD>
- <TD><DIVDATAFLD=FirstName></DIV></TD>
- </TR>
- </TABLE>
第三步:然後,增加一對DTCs Button按鈕控件來做翻頁導航,一個命名為btnPrevious(上一頁),一個命名為btnNext(下一頁)。它們相應的腳本如下:
- <SCRIPTLANGUAGE=VBScript>
- FunctionbtnPrevious_onclick()
- Table1.previousPage()
- EndFunction
- FunctionbtnNext_onclick()
- Table1.nextPage()
- EndFunction
- </SCRIPT>
第五種:DHTML法二
這種方法是對第四種方法的完善。採用手工編寫腳本的方法,使我們能做首頁,末頁翻頁導航按鈕,並能確定每條記錄的位置(記錄號)。由於篇幅的關係,我在下面只介紹一個具體例子,並給出簡要說明。其它關於DHTML和Recordset控件的一些屬性和方法請讀者自行參照相關書籍。這裡需要提請注意的是,Recordset控件與第一、二種方法中介紹的ADO的Recordset對像有些不同:Recordset控件沒有直接給出pagesize和pagecount等屬性,需要用下面介紹的方法來計算。
第一步:拖Recordset控件到新建的網頁emp5.htm中,名字為Recordset1,設置其屬性,方法同第三種,此處略。
第二步:定義三個全局變量和編寫Recordset1的ondatasetcomplete(數據設置完成時)腳本。
- DimgCurrentPageNumber//當前頁號
- DimgMaxPageNumber//最大頁數
- DimgRecordsPerPage//每頁顯示記錄數
- gRecordsPerPage=5//設置每頁顯示記錄數為5條記錄。
- FunctionRecordset1_ondatasetcomplete()
- totalRecordCount=Recordset1.getCount()//總的記錄條數
- gMaxPageNumber=Int(totalRecordCount/gRecordsPerPage)//獲得最大頁數
- If(totalRecordCountModgRecordsPerPage)>0then
- gMaxPageNumber=gMaxPageNumber+1
- EndIf
- EndFunction
第三步:創建翻頁導航按鈕。
- FunctionbtnFirst_onclick()'翻到首頁
- gCurrentPageNumber=1
- DisplayData()
- EndFunction
- FunctionbtnPrevious_onclick()'翻到上一頁
- ifgCurrentPageNumber>1Then
- gCurrentPageNumber=gCurrentPageNumber-1
- DisplayData()
- EndIf
- EndFunction
- FunctionbtnNext_onclick()'翻到下一頁
- ifgCurrentPageNumber<gMaxPageNumberThen
- gCurrentPageNumber=gCurrentPageNumber+1
- DisplayData()
- EndIf
- EndFunction
- FunctionbtnLast_onclick()'翻到末頁
- gCurrentPageNumber=gMaxPageNumber
- DisplayData()
- EndFunction
第四步:編寫顯示每一頁的函數。其中使用了許多DHTML的屬性和方法,請讀者自行參考相關書籍。
- SubDisplayData()
- startRecord=((gCurrentPageNumber-1)*gRecordsPerPage)+1//計算每一頁開始顯示的記錄號數(位置,第幾條)
- rowCtr=1
- lblPageNumber.innerHTML=gCurrentPageNumber&/&gMaxPageNumber
- ForrecordPtr=startRecordTo(startRecord+gRecordsPerPage-1)//循環顯示一頁的各條記錄
- IfrecordPtr>Recordset1.getCount()Then//顯示空表
- Table1.rows(rowCtr).cells(0).innerHTML=<P></P>
- Table1.rows(rowCtr).cells(1).innerHTML=<P></P>
- Table1.rows(rowCtr).cells(2).innerHTML=<P></P>
- Table1.rows(rowCtr).cells(3).innerHTML=<P></P>
- Else//具體顯示每一頁
- Recordset1.moveAbsolute(recordPtr)//移動記錄指針。
- empID=Recordset1.fields.getValue(empID)
- empLName=Recordset1.fields.getValue(firstname)
- empFName=Recordset1.fields.getValue(lastname)
- Table1.rows(rowCtr).cells(0).innerText=recordPtr'Counter
- Table1.rows(rowCtr).cells(1).innerText=empID
- Table1.rows(rowCtr).cells(2).innerText=empLName
- Table1.rows(rowCtr).cells(3).innerText=empFName
- EndIf
- rowCtr=rowCtr+1
- Next
- EndSub
另外,我們還需要在window對象的onload事件中編寫如下腳本:
- ForrowCtr=1togRecordsPerPage
- Table1.insertRow(rowCtr)'插一新列
- ForcellCtr=0to3
- Table1.rows(rowCtr).insertCell()
- Next
- Next
第六種:服務器端控制翻頁方法。
如果我們在服務器端對數據進行分頁形成HTML語句後再輸出到客戶端,就不會存在瀏覽器不支持DHTML的問題了。可是用服務器端法使得我們每次翻頁時,都得讓Recordset控件重新產生一次,因此速度肯定要比用DHTML的方法慢。但如果服務器足夠快的話,這點慢客戶是察覺不到的。
下面的例子中,我將介紹一個新的DTC控件:PageObject。這個控件使被指定的網頁成為一個網頁對象,用戶在此網頁的服務器腳本中組織的子程序和函數可被看作是該網頁對象的方法。它提供了管理狀態信息的一種先進的方法:網頁對像有一些屬性(變量),用戶可以定義這些屬性的生存期。因為以上這些特性,使我們在編制翻頁的腳本時非常方便。
但這種方法的缺點是:當你按了上頁或下頁按鈕後,再瀏覽器上的按刷新按鈕,網頁會自動翻頁。另外,如果按了瀏覽器上的回退按鈕後,再按翻頁按鈕,可能會出現一次亂翻。這都是因為網頁對象屬性(全局變量)造成的。
第一步:拖Recordset控件到新建的網頁emp6.asp中,名字為Recordset1,設置其屬性,方法同第三種,此處略。
第二步:拖PageObject控件到網頁中,取名叫emplist。然後右鍵單擊此控件打開屬性頁並設置MaxPageNumber,RecordsPerPage,CurrrentPageNumber三個屬性(全局變量)。 VI6.0可用get和set方法來讀寫它們的值,具體用法請查閱相關資料。
第三步:編寫Recordset1的ondatasetcomplete事件。
- FunctionRecordset1_ondatasetcomplete()
- recordsPerPage=5
- empList.setRecordsPerPage(recordsPerPage)//設置網頁對象每頁記錄條數屬性為5
- totalRecordCount=Recordset1.getCount()//獲得記錄集的總條數
- mpn=Int(totalRecordCount/recordsPerPage)//計算出mpn為總頁數
- If(totalRecordCountModrecordsPerPage)>0then
- mpn=mpn+1
- EndIf
- empList.setMaxPageNumber(mpn)
- EndFunction
第四步:拖四個button控件到網頁中,編寫翻頁控制腳本。我們主要是通過改變網頁對象的CurrentPageNumber屬性的值來實現翻頁。
- FunctionbtnFirst_onclick()'翻到首頁
- empList.setCurrentPageNumber(1)
- EndFunction
- FunctionbtnPrevious_onclick()'翻到上一頁
- cpn=empList.getCurrentPageNumber()
- ifcpn>1Then
- empList.setCurrentPageNumber(cpn-1)
- EndIf
- EndFunction
- FunctionbtnNext_onclick()'翻到下一頁
- cpn=empList.getCurrentPageNumber()
- ifcpn<empList.getMaxPageNumber()then
- empList.setCurrentPageNumber(cpn+1)
- EndIf
- EndFunction
- FunctionbtnLast_onclick()'翻到末頁
- empList.setCurrentPageNumber(empList.getMaxPageNumber())
- EndFunction
為保證首次進入該頁時,顯示的是第一頁,我們還得編寫該網頁對象的onEnter事件。
- FunctionempList_onEnter()
- IfempList.firstEnteredThen
- empList.setCurrentPageNumber(1)
- EndIf
- EndFunction
- 第五步:編寫顯示每一頁的腳本。
- <HR><TABLEBORDER=0><TR>//顯示表頭
- <THALIGN=leftWIDTH=35></TH>
- <THALIGN=leftWIDTH=150>EmpID</TH>
- <THALIGN=leftWIDTH=200>LastName</TH>
- <THALIGN=leftWIDTH=200>FirstName</TH></TR>
- <%
- pageNumber=empList.getCurrentPageNumber()//計算翻頁所需的各種參數,同DHTML法二
- recordsPerPage=empList.getRecordsPerPage()
- startRecord=((pageNumber-1)*recordsPerPage)+1
- lastRecord=Recordset1.getCount()
- ForrecordPtr=startRecordTo(startRecord+recordsPerPage-1)%>
- <%IfRecordset1.EOF=TrueThen%>
- <TR>
- <TD></TD>
- <TD></TD>
- <TD></TD>
- <TD></TD>
- </TR>
- <%Else%>
- <%Recordset1.moveAbsolute(recordPtr)%>
- <TR>
- <%IfrecordPtr<=lastRecordThen%>
- <TD><%=recordptr%></TD>
- <%Else%>
- <TD></TD>
- <%EndIf%>
- <TD><%=Recordset1.fields.getValue(empID)%></TD>
- <TD><%=Recordset1.fields.getValue(lastname)%></TD>
- <TD><%=Recordset1.fields.getValue(firstname)%></TD>
- </TR>
- <%EndIf%>
- <%Next%>
- </TABLE><HR>
第七種:Data Environment Object Model(數據環境對像模型)法
Data Environment對像模型把ADO對像模型及它的對象----Connection,Command,Recordset,Field以及Parameter對象----抽像到一個更加容易的表單中。 Data Environment Object Model把命令顯露為方法。用戶可以調用這些方法,這些方法會執行這些命令並返回所得到的記錄集。關於DEOM對像模型詳細資料請參考相關書籍。我們來看下面網頁emp7.asp的例子:
第一步:在VI6.0的project Explorer窗口中的工程項目上右擊鼠標並從彈出式菜單選擇Add Data Connection。根據VI給出的導航提示建立一個到數據庫的連接之後,用戶就添加了一個實現從ASP應用程序訪問數據庫的數據命令。同時,你將會在Project Explorer窗口中的global.asa文件下方看到一個Data Environment對象。
第二步:右擊Data Environment對象然後從彈出式菜單中選擇Add Data Command選項,添加一個數據命令Command1。根據VI6.0的導航提示,你可以在Command1 Properties彈出窗口的Genetal頁中選SQL Statement,輸入:select * from emp。按OK返回。
第三步:你創建了這個數據命令後,就已經為該Data Environment對象創建了一個方法,然後就可以從腳本中調用這個方法,而且該方法將會給用戶返回一個記錄集。
thisPage.createDE() //在SOM模式下,thisPage表示當前網頁對象,createDE()方法創建了DE對象。
DE.Command1//執行DE對象的命令,後面可代參數,做有條件查詢時很有用。
Set rs=DE.rsCommand1//DE.rscommand1使得rs對象完全等同於一個ADO的Recordset對象。
第四步:因為rs為ADO對象,所以,以下的實現翻頁代碼完全參照以上介紹的幾種方法,此處略過。
其它還有如FrontPage2000的數據庫導航中實現的方法等,因與本主題無關,此處略。
綜上所述,前面介紹的每種方法都包含了很多新的技術,由於篇幅的關係,無法深入。本文只是想通過實現翻頁這一具體的例子來介紹ASP網頁編程的多種方法;讓大家親身體驗一下VI6.0在編制網頁中的強大功能;了解和熟悉微軟在網頁編程中提出的ADO、 DHTML、DTC控件、SOM對像模型和DEOM對像模型的使用方法;希望能給大家在編制網頁時提供更多的選擇和參考。