4

我需要根据消费者可以设置的一些处理和一些属性在 WebControl 中输出一些 JavaScript,在页面加载时执行此操作会为时过早。

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

4

4 回答 4

6

老问题,但我最近处理了这个问题,所以让蒂姆的回答更清楚一点,并清除一些错误信息:

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

这是顺序:

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

从反射器:

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();
    }
}

注意对 page.BeginFormRender 和 page.EndFormRender 的调用。在它们之间,表单调用它的 base.RenderChildren 最终将调用自定义用户控件上的 Render 方法。因此,对于您的原始问题,您不能在任何子控件的渲染序列期间随时与脚本的 ClientScriptBlocks 部分进行交互,因为它们已经输出到响应流。如果您在调用 base.Render 之前处于 Page 的 Render 方法中,则可以在 Render 序列期间将脚本添加到此块,正如 Tim 所提到的,但这在任何类型的子控件中都不起作用。

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

于 2008-12-29T22:10:13.437 回答
3

预渲染

或者,如果您在调用“base.Render”之前覆盖 Render....

于 2008-10-31T12:07:54.593 回答
1

从逻辑上讲,您的启动脚本需要在页面上进行渲染和注册,因此 Page_PreRender 事件似乎是一个不错的选择。之后,页面的 HTML 和脚本被“锁定”。

于 2008-10-31T12:12:22.617 回答
1

即使在主页上,您也可以在 PreRender 期间调用它。每个控件的 Render 函数在主页面的 PreRender 之后调用,因此 Render 函数将是一个安全的地方。

于 2008-10-31T12:17:23.247 回答