[译]用PageMethods/AJAX填充HTML表格

这篇文章展示如何用ASP.NET AJAX的PageMethods方法与HTML表格来实现增删查改。在这里HTML表格充当一个轻量性的DataGrid的功能。
为了使用PageMethods方法,我们必须满足以下条件:
  1.页面中必须包含ScriptManager控件
  2.设置ScriptManager控件的EnablePageMethods属性为true
  3.页面后台代码需要引用System.Web.Services命名空间
  4.页面后台代码需要用[WebMethod]来标记PageMethods方法
  首先我们先来实现查询功能
  如上所说,在页面上增加一个ScriptManager控件并把属性EnablePageMethods设置为true。增加一个HTML按钮并设置它的onclick事件,然后增加一个带有thead,tbody和tfoot的HTML表格。既然HTML表格将被javascript调用,因而为其和它的body分别增加一个id。在这里,因为只使用HTML标记及控件,所有服务器端的控件将不能被PageMethods调用。

  ASPX页面如下:

代码
<body>
    
<form id="form1" runat="server">  
        
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods ="true" ></asp:ScriptManager>
        
<%--This click event handles loading data from the database--%>
        
<input id="btn_load" type="button" value="Load" onclick = "LoadData()" />
        
<br /><br />
    
<div>
        
<table style=" height: 100%; border: solid 1px #000" cellpadding="0" cellspacing="1" id="tbl_grid" border = "1">
            
<thead style = "background-color: #666; color: #fff">
                
<tr>
                    
<td style="width: 100px;">
                        Column1
                    
</td>
                    
<td style="width: 500px;">
                        Column2
                    
</td>
                    
<td style="width: 150px;">
                        Edit
                    
</td>
                
</tr>
            
</thead>
            
<tbody id="tbody_grid">
            
</tbody>
            
<tfoot>
                
<tr>
                    
<td style="width: 100px;">
                        
<input id="txt_addcol1" style ="width: 30px" type="text" />
                    
</td>
                    
<td style="width: 500px;">
                        
<input id="txt_addcol2" type="text"  style ="width: 300px" />
                    
</td>
                    
<td style="width: 150px;">                  
                        
<%--This click event handles adding data to the database--%>
                        
<input id="btn_add" type="button" onclick = "Add()" value="Add" />
                    
</td>
                
</tr>
            
</tfoot>
        
</table>
    
</div>
    
</form>
</body>

  现在增加一个名为LoadData()的javascript函数,用来从数据库读取数据。PageMethod调用应该总是有一个成功的回调函数(此函数在PageMethod执行成功时调用)和一个异常处理函数(此函数在出现异常时被调用)。假如我们在后台增加一个GetData()并标记为[WebMethod],则前台的javascript在调用的方式为:PageMethods.GetData(SuccessHandler, ExceptionHandler)。为了便于理解,我为成功和异常处理函数起了一个适当的名称。当然你可以给它们起一个你喜欢的名字。如果PageMethod方法带有参数,你可以像这样调用它:PageMethods.GetData(param1, param2, SuccessHandler, ExceptionHandler)。


  通过PageMethods调用的方法必须标记[WebMethod]并且必须是静态的方法。声明如下:
[WebMethod]
public static string GetData()
  取数据的方法:
代码
public partial class AJAXGrid : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    {
    }
    [WebMethod]
    
public static IEnumerable<MyEntity> GetData()
    {
        
try
        {                 
        Data fetch part should go here
        // used List, as collections are serializable. See below for MyEntity class
        List<MyEntity> MyEntities = new List<MyEntity>();
        MyEntities.Add("1""abc");
        MyEntities.Add("2""xyz");
        MyEntities.Add("3""pqr");
        MyEntities.Add("4""mno");
        return MyEntities;
     }
        
catch(Exception ex)
        {
            
throw ex;
        }
    }
}
  MyEntity实体类
代码
public class MyEntity
{
    
private string _Column1;
    
public string Column1
    {
      
get { return _Column1; }
      
set { _Column1 = value; }
    }
    
private string _Column2;
    
public string Column2
    {
      
get { return _Column2; }
      
set { _Column2 = value; }
    }
    
public MyEntity(string sCol1, string sCol2)
    {
        _Column1 = sCol1;
        _Column2 = sCol2;
    }
}

  用来调用后台的方法并填充HTML表格的javascript函数  

代码
<script type ="text/javascript" language = "javascript ">
    
//Loading Data
    // Handles btn_load click event
    function LoadData() {
        
// If data was fetched successfully, SuccessHandler will be called; else, ExceptionHandler
        PageMethods.GetData(SuccessHandler, ExceptionHandler);
       
// Incase parameters need to be passed to PageMethods, you can do like this PageMethods.GetData(param1, param2, SuccessHandler, ExceptionHandler)
    }
    
// After fetching the data successfully
    function SuccessHandler(result) {
        
var tbody = $get("tbody_grid");
        
// clear the table
        for (var j = tbody.rows.length; j > 0; j--) {
            tbody.deleteRow(j 
- 1);
        }
        
// populate the table
        for (var i = 0; i < result.length; i++) {
            
//two columns fetched from database are sent as parameters
            AddRow(result[i].Column1, result[i].Column2);        
        }
        
return true;
    }
    
// Edit and Delete buttons are added to the rows
    function AddRow(col1, col2) {
        
var tbody = $get("tbody_grid");
        
var row = document.createElement("tr")
        
var td1 = document.createElement("td")
        td1.innerText 
= col1;
        
var td2 = document.createElement("td");
        td2.innerText 
= col2;
        
var td3 = document.createElement("td");
        
// add buttons
        var btnEdit = document.createElement('input');
        btnEdit.setAttribute(
'type''button');
        btnEdit.setAttribute(
'name''Edit');
        btnEdit.setAttribute(
'value''Edit');
        
// first parentNode represents <td> and the second represents <tr>
        btnEdit.onclick = function() { Edit(this.parentNode.parentNode); };
        
var btnDelete = document.createElement('input');
        btnDelete.setAttribute(
'type''button');
        btnDelete.setAttribute(
'name''Delete');
        btnDelete.setAttribute(
'value''Delete');
        btnDelete.onclick 
= function() { DeleteRow(this.parentNode.parentNode); };
        td3.appendChild(btnEdit);
        td3.appendChild(btnDelete);
        row.appendChild(td1);
        row.appendChild(td2);
        row.appendChild(td3);
        tbody.appendChild(row);       
    }
    
// Handles exception
    function ExceptionHandler(result) {

    }


  填充数据后的截图:


  用来实现增删查改的javascript函数

  编辑数据

 

代码
//  this function handles edit button click
    function Edit(row) {
        
var col1 = row.childNodes[0].innerText;
        
var col2 = row.childNodes[1].innerText;
        
// populates values in textboxes and displays Update and Cancel buttons
        var editableRow = document.createElement("tr")
        
var td1 = document.createElement("td")
        
var txtBox1 = document.createElement('input');
        txtBox1.setAttribute(
'type''text');
        txtBox1.setAttribute(
'name''col1');
        txtBox1.setAttribute(
'value', col1);
        txtBox1.setAttribute(
'width'30);
        td1.appendChild(txtBox1);
        
var td2 = document.createElement("td");
        
var txtBox2 = document.createElement('input');
        txtBox2.setAttribute(
'width'300);
        txtBox2.setAttribute(
'type''text');
        txtBox2.setAttribute(
'name''col1');
        txtBox2.setAttribute(
'value', col2);
        td2.appendChild(txtBox2);
        
var td3 = document.createElement("td");
        
var btnUpdate = document.createElement('input');
        btnUpdate.setAttribute(
'type''button');
        btnUpdate.setAttribute(
'name''Update');
        btnUpdate.setAttribute(
'value''Update');
        btnUpdate.onclick 
= function() { Update(this.parentNode.parentNode); };
        
var btnCancel = document.createElement('input');
        btnCancel.setAttribute(
'type''button');
        btnCancel.setAttribute(
'name''Cancel');
        btnCancel.setAttribute(
'value''Cancel');
        btnCancel.onclick 
= function() { Cancel(this.parentNode.parentNode); };
        td3.appendChild(btnUpdate);
        td3.appendChild(btnCancel);
        editableRow.appendChild(td1);
        editableRow.appendChild(td2);
        editableRow.appendChild(td3);
        row.parentNode.replaceChild(editableRow, row);
    }
  单击Edit按钮后的截图:

  更新数据

代码
//  this function handles update button click
    function Update(row) {
        
// fetches values entered in the textboxes
        // first childNode represent <td> inside <tr> and second childNode represents textbox
        var col1 = row.childNodes[0].childNodes[0].value;
        
var col2 = row.childNodes[1].childNodes[0].value;
        
// values sent to server
        PageMethods.UpdateData(col1, col2, UpdateSuccess(row), ExceptionHandler);      
    }
    
// After updating the values successfully
    function UpdateSuccess(row) {
        
var col1 = row.childNodes[0].childNodes[0].value;
        
var col2 = row.childNodes[1].childNodes[0].value;
        
var editableRow = document.createElement("tr")
        
var td1 = document.createElement("td")
        td1.innerText 
= col1;
        
var td2 = document.createElement("td");
        td2.innerText 
= col2;
        
var td3 = document.createElement("td");
        
var btnEdit = document.createElement('input');
        btnEdit.setAttribute(
'type''button');
        btnEdit.setAttribute(
'name''Edit');
        btnEdit.setAttribute(
'value''Edit');
        btnEdit.onclick 
= function() { Edit(this.parentNode.parentNode); };
        
var btnDelete = document.createElement('input');
        btnDelete.setAttribute(
'type''button');
        btnDelete.setAttribute(
'name''Delete');
        btnDelete.setAttribute(
'value''Delete');
        btnDelete.onclick 
= function() { DeleteRow(this.parentNode.parentNode); };
        td3.appendChild(btnEdit);
        td3.appendChild(btnDelete);
        editableRow.appendChild(td1);
        editableRow.appendChild(td2);
        editableRow.appendChild(td3);
        row.parentNode.replaceChild(editableRow, row);
    }
    
// this function handles cancel button click
    function Cancel(row) {
        
// values are again populated in labels instead of textboxes
        var col1 = row.childNodes[0].childNodes[0].value;
        
var col2 = row.childNodes[1].childNodes[0].value;
        
var editableRow = document.createElement("tr")
        
var td1 = document.createElement("td")
        td1.innerText 
= col1;
        
var td2 = document.createElement("td");
        td2.innerText 
= col2;
        
var td3 = document.createElement("td");
        
var btnEdit = document.createElement('input');
        btnEdit.setAttribute(
'type''button');
        btnEdit.setAttribute(
'name''Edit');
        btnEdit.setAttribute(
'value''Edit');
        btnEdit.onclick 
= function() { Edit(this.parentNode.parentNode); };
        
var btnDelete = document.createElement('input');
        btnDelete.setAttribute(
'type''button');
        btnDelete.setAttribute(
'name''Delete');
        btnDelete.setAttribute(
'value''Delete');
        btnDelete.onclick 
= function() { DeleteRow(this.parentNode.parentNode); };
        td3.appendChild(btnEdit);
        td3.appendChild(btnDelete);
        editableRow.appendChild(td1);
        editableRow.appendChild(td2);
        editableRow.appendChild(td3);
        row.parentNode.replaceChild(editableRow, row);
    }
    
//  this function handles 'add' button click
    function Add() {
        
var col1 = $get("txt_addcol1").value;
        
var col2 = $get("txt_addcol2").value;
        
// data sent to the database
        PageMethods.InsertData(col1, col2, AddSuccess(col1, col2), ExceptionHandler);        
    }
    
// After adding the data successfully
    function AddSuccess(col1, col2) {
        
// add the values to the table
        AddRow(col1, col2);
        
// clear the textboxes in the footer
        $get("txt_addcol1").value = "";
        $get(
"txt_addcol2").value = "";
    }

  删除数据

代码
// this function handles delete button click
    function DeleteRow(row) {
        
var col1 = row.childNodes[0].innerText;
        
// delete from the database
        PageMethods.DeleteData(col1, DeleteSuccess(row), ExceptionHandler);
    }
    
function DeleteSuccess(row) {
        
// delete the row from the table
        var tbody = $get("tbody_grid");
        tbody.removeChild(row);
    }
</script>

  处理增删查改的PageMethod方法

代码
    [WebMethod]
    
public static void UpdateData(string sCol1, string sCol2)
    {
        
try
        {                  
             Data update part should go here     
        }
        
catch(Exception ex)
        {
            
throw ex;
        }
    }
    [WebMethod]
    
public static void InsertData(string sCol1, string sCol2)
    {
        
try
        {
                          Data insert part should go here        
        }
        
catch(Exception ex)
        {
            
throw ex;
        }
    }
    [WebMethod]
    
public static void DeleteData(string sCol1)
    {
        
try
        {
                           Data delete part should go here         
        }
        
catch (Exception ex)
        {
            
throw ex;
        }
    }
}

  还可以为其增加分页及排序功能。

  代码在IE7+,Firefox,Chrome和Safari中测试成功。

  使用ASP.NET AJAX的PageMethods方法的一些限制:
    1.在[WebMethod]标记的方法中不能直接访问服务端控件(如textbox)
    2.不能访问后台代码中声明的任何变量
posted @ 2009-12-26 11:43  Jack Tong  阅读(825)  评论(0编辑  收藏  举报