技术开发 频道

使用js刷新UpdatePanel

  【IT168技术】假设我们有一个展示产品信息的列表。其中的某几列需要添加排序的功能,当然可以选择使用gridview本身的排序功能,但效率太低,一般我们会选择使用AJAX来实现。

  OK,将这个列表置入UpdatePanel,这时点击需要排序的列的列头(标题)就需要触发一个回发事件,很常见的方式就是在在UpdatePanel内添加一个隐藏的按钮(或updatepanel外并设置该按钮为updatepanel的异步触发器),然后在点击列头时触发按钮的click事件即可。

  下面以一个更简单的例子来描述上面的情形:

...
<body>
<script type="text/javascript">
    
function doRefresh() {
        document.getElementById(
'<%= btnRefresh.ClientID %>').click();
    }
    
</script>
    
<form id="form1" runat="server">
    
<div>
        
<asp:ScriptManager ID="sm" runat="server">
        
</asp:ScriptManager>
        
<asp:UpdatePanel ID="pnlTime" runat="server">
            
<ContentTemplate>
                
<asp:Label ID="lblTime" runat="server" />
                
<asp:Button ID="btnRefresh" runat="server" style="display:none"  OnClick="btnRefresh_Click"/>
            
</ContentTemplate>
        
</asp:UpdatePanel>
        
        
<div onmouseover="doRefresh()">鼠标划过时更新时间</div>
    
</div>
    
</form>
</body>
...

            在Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Refreshing An UpdatePanel With JavaScript 这篇文章中还介绍了一种方式:

<body>
<script type="text/javascript">
    
function doRefresh() {
        
<%=ClientScript.GetPostBackEventReference(pnlTime, "") %>;
    }
    
</script>
    
<form id="form1" runat="server">
    
<div>
        
<asp:ScriptManager ID="sm" runat="server">
        
</asp:ScriptManager>
        
<asp:UpdatePanel ID="pnlTime" runat="server">
            
<ContentTemplate>
                
<asp:Label ID="lblTime" runat="server" />
            
</ContentTemplate>
        
</asp:UpdatePanel>
        
        
<div onmouseover="doRefresh()">鼠标划过时更新时间</div>
    
</div>
    
</form>
</body>

  这里使用了ClientScript.GetPostBackEventReference,最终生成的前台代码如下:

function doRefresh() {
        __doPostBack(
'pnlTime','');
    }



  这样也能达到我们的目的。

  而这种方式相应的后台代码如下:

public partial class WebForm1 : System.Web.UI.Page
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            lblTime.Text
= DateTime.Now.ToString("hh:mm:ss");
        }
    }

         表明该种实现方式其实是利用了即使是异步postback,也会触发页面的完整生命周期的原理。

  虽然这种方式在简单情形下很有效,但也存在一个很严重的弊端:没有对应的处理回发事件的地方,像上面的例子就只能在Page_Load里处理。如果一个页面只有一个按钮会引起回发,那么我们也完全可以不用设置该按钮的OnClick事件,而在Page_Load等中进行处理。但是如果很多按钮呢,映射到上面的例子:如果还需要点击div显示完整的日期呢?这种方式就捉襟见肘了。

  这时候我想到了从UpdatePanel入手:如果UpdatePanel自身能处理回发事件就好了。于是一个自定义的UpdatePanel产生了:

namespace MyControls
{
    
public delegate void PostBack(string source);
    
public class MyUpdatePanel : UpdatePanel, IPostBackEventHandler
    {
        
public static object PostBackObj = new object();
        
public event PostBack PostBack
        {
            add
            {
                Events.AddHandler(PostBackObj, value);
            }
            remove
            {
                Events.RemoveHandler(PostBackObj,value);
            }
        }
        
#region IPostBackEventHandler Members

        
public void RaisePostBackEvent(string source)
        {
            
if( Events[PostBackObj] != null)
            {
                var handler
= (MyControls.PostBack) Events[PostBackObj];
                handler(source);
            }
        }

        #endregion
    }

  MyUpdatePanel 不仅具有UpdatePanel的所有功能,还能够处理回发事件。这样实现点击div显示完整的日期就很容易了。

<body>
<script type="text/javascript">
    
function showFullTime()
    {
  
<%=ClientScript.GetPostBackEventReference(pnlTime, "click") %>;
    }
    
function refreshTime()
    {
        
<%=ClientScript.GetPostBackEventReference(pnlTime, "over") %>;
    }
  
    
</script>
    
<form id="form1" runat="server">
    
<div>
        
<asp:ScriptManager ID="sm" runat="server">
        
</asp:ScriptManager>
        
<asp:MyUpdatePanel ID="pnlTime" runat="server" OnPostBack="Refresh">
            
<ContentTemplate>
                
<asp:Label ID="lblTime" runat="server" />
            
</ContentTemplate>
        
</asp:MyUpdatePanel>
        
        
<div onmouseover="refreshTime()" >鼠标划过时更新时间</div>
        
<div onclick="showFullTime()">点击显示完整时间</div>
    
</div>
    
</form>
</body>  
  Refresh的定义如下:

protected void Refresh(string type)
        {
            switch (type)
            {
                
case  "over":
                    lblTime.Text
= DateTime.Now.ToString("hh:mm:ss");
                    break;
                
case "click":
                    lblTime.Text
= DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
                    break;
            }
        }

这样我们就比较完善地实现了不添加辅助按钮,仅用JS刷新UpdatePanel了。

    演示用到代码下载

0
相关文章