ScriptManager.RegisterClientScriptBlock注册脚本两次
问题描述:
在我的自定义服务器控件的OnPreRender上,我注册了一个警报,在每次页面在部分回传后加载时弹出(add_pageLoaded(function(){alert('Hi')})) 。我只希望这个被调用一次,但它被调用的次数与部分回发一样多。例如,在下面的代码中,如果您打开页面并单击“单击我”,您将看到一个警报,再次单击,您将看到两个警报,三个>三个警报等等。我的理解是ScriptManager.RegisterClientScriptBlock,使用scriptKey参数假设检查脚本是否已经注册,如果是的话,不要再注册它。 我无法在!IsPostBack上注册此脚本!因为我的自定义控件将在回发期间插入到页面中,所以使用!IsPostBack将不包含我的脚本。ScriptManager.RegisterClientScriptBlock注册脚本两次
下面是这个问题的一个简单的例子:
ASPX:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="RegisterClientScriptExperimentation._Default" %>
<%@ Register Assembly="RegisterClientScriptExperimentation" Namespace="RegisterClientScriptExperimentation" TagPrefix="cc" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Panel ID="panel" runat="server"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
后面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
namespace RegisterClientScriptExperimentation
{
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
panel.Controls.Add(new CustomControl());
}
}
public class CustomControl : CompositeControl
{
private Button button;
public CustomControl()
{
button = new Button();
button.Text = "Click me";
}
protected override void CreateChildControls()
{
Controls.Clear();
Controls.Add(button);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
StringBuilder _text = new StringBuilder();
_text.Append("var prm = Sys.WebForms.PageRequestManager.getInstance();");
_text.Append("prm.add_pageLoaded(function() { alert('Page Loaded'); });");
if (null != System.Web.UI.ScriptManager.GetCurrent(Page) && System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "customControlScript", _text.ToString(), true);
else
Page.ClientScript.RegisterStartupScript(this.GetType(), "customControlScript", _text.ToString(), true);
}
}
}
答
我找到了解决这个。
在你的页面事件中,当你执行你需要做的任何事情之后,你需要从你插入的事件中去掉这个函数。
例如:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(DoSomething);
function DoSomething() {
alert('Hello');
Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(DoSomething);
}
答
if(!Page.ClientScript.IsClientScriptBlockRegistered("customControlScript") && !Page.IsPostBack)
{
if (null != System.Web.UI.ScriptManager.GetCurrent(Page) && System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "customControlScript", _text.ToString(), true);
else
Page.ClientScript.RegisterStartupScript(this.GetType(), "customControlScript", _text.ToString(), true);
}
我插入这个控制插入部分回发的网页,所以我不能检查Page.IsPostBack因为控制将在回发加入!我尝试没有IsPostBack,它似乎总是返回未注册。我不认为你可以使用Page.ClientScript方法来检查使用ScriptManager注册的脚本 – BlueChameleon 2012-04-06 18:23:05