JS触发服务端控件回发以及触发AJAX.NET控件回发的整理
1、服务端控件
后台注册下客户端的回发事件
例子1:
this.Page.ClientScript.GetPostBackEventReference(控件ID, string.Empty);
例子2:
this.bt_refresh.Attributes["click"] = this.Page.ClientScript.GetPostBackEventReference(this, " ");
前端JS函数的调用
__doPostBack('<%= bt_refresh.ClientID %>', '');
比如asp:Button就会触发按钮默认的服务端的onclick事件!
2、AJAX.NET控件
1)动态刷新
function test()
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
alert('<%= bt_refresh.ClientID %>');
prm._doPostBack('<%= bt_refresh.ClientID %>', '');
}
2)AJAX刷新
<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显示完整的日期就很容易了。
再前部注册下控件
<%@ Register Assembly="程序集" Namespace="MyUpdatePanel 所在命名空间" TagPrefix="asp" %>
<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了。