什么时候绝对最新你可以调用Page.ClientScript.RegisterClientScriptBlock?

Kie*_*ron 4 javascript c# asp.net web-controls

我需要在WebControl中输出一些JavaScript,这些JavaScript基于一些处理和消费者可以设置的一些属性,在页面的加载上执行它将是早期的.

什么是最新的我可以调用RegisterClientScriptBlock并仍然在页面输出?

sli*_*les 6

老问题,但我最近处理了这个问题,所以要给蒂姆的答案一点澄清,并澄清一点错误信息:

如果您使用的是RegisterClientScriptBlock,那么您的脚本将在ClientScriptManager.RenderClientScriptBlocks期间输出,该脚本在Page.BeginFormRender期间调用 - 但它实际上是由Form调用的,而不是由Page本身调用的.

这是顺序:

  • Page.ProcessRequestMain(当它到达渲染部分时)调用
  • (Page的基类)调用的Control.RenderControl
  • Control.RenderChildren循环遍历所有子控件并最终调用
  • 调用HtmlForm.RenderControl
  • HtmlForm.RenderChildren这是我们关心的

来自Reflector:

protected internal override void RenderChildren(HtmlTextWriter writer)
{
    Page page = this.Page;
    if (page != null)
    {
        page.OnFormRender();
        page.BeginFormRender(writer, this.UniqueID);
    }
    base.RenderChildren(writer);
    if (page != null)
    {
        page.EndFormRender(writer, this.UniqueID);
        page.OnFormPostRender();
    }
}
Run Code Online (Sandbox Code Playgroud)

注意对page.BeginFormRender和page.EndFormRender的调用.在它们之间,表单调用它的base.RenderChildren,它最终将在您的自定义用户控件上调用Render方法.因此,要忠实于原始问题,在任何子控件的渲染序列中,您都不能随时与脚本的ClientScriptBlocks部分进行交互,因为它们已经输出到Response流.您可以渲染序列中,如果你是在页面的渲染方法调用base.Render之前,蒂姆提到这个块添加脚本,但这并不能在任何类型的子控件工作.

如果渲染序列是您必须使用的全部(这就是我所处的情况),那么您可以在控件的渲染期间使用ClientScript.RegisterStartupScript,因为在page.EndFormRender期间调用RenderClientStartupScripts,这您的控件被告知之后发生渲染,正如您在上面的代码中看到的那样.