【问题标题】:Async postback doesn't cause document.ready to be executed异步回发不会导致 document.ready 被执行
【发布时间】:2011-04-10 16:00:17
【问题描述】:

我不得不对几个页面中使用的用户控件进行一些更改。用户控件包含一些 JQuery 来处理分页任务(显示 3 个月的数据,一次隐藏 9 个)。控件加载后会自动显示当前季度,并在$(document).ready()中执行这段代码。

我遇到的问题是,在使用用户控件的页面之一中,该控件在页面加载时不可见。异步回发用于更改可见性,但这不会执行 ready()。

我发现了一个 sn-p,它允许托管页面拦截部分回发的 EndResponse,但我仍然无法在用户控件中执行该功能。

有人有什么建议吗?

干杯

戴夫

【问题讨论】:

标签: asp.net jquery


【解决方案1】:

和我一样,你会讨厌微软规定的答案。 “规定”的答案是使用 PageRequestManager 来设置请求处理程序。此请求处理程序(然后)在每个部分回发完成后执行。

请求处理程序示例:

<script id="events" type="text/javascript">

    jQuery(document).ready(function() {

        // Your normal code goes here
        setupSomething();
        initializeSomethingElse();

        // Setup your partial-postback event handler.
        // This is used to rewire all events since all are 'lost' after partial-postback.
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(requestHandler);
    });

    ///<summary>partial postback event handler. Executed after the partial postback is completed. Clears modal popup textboxes</summary>
    ///<param name="sender"></param>
    ///<param name="args">http://www.asp.net/ajax/documentation/live/ClientReference/Sys.WebForms/EndRequestEventArgsClass/default.aspx</param>
    function requestHandler(sender, args) {

        if (args.get_error() == undefined) {

            // Your normal code goes here
            setupSomething();
            initializeSomethingElse();
        }
        else
            alert(args.get_error()); // Do something
    }
</script>

这给我们带来了简单的答案:
为什么不从您的代码隐藏显式初始化您的用户控件,并将初始化 JavaScript 保留在您的用户控件 HTML(本身)中。

void YourUserControl_PreRender(object sender, EventArgs e)
{
    try
    {

    }
    catch (Exception ex)
    {

    }
    finally 
    {
        // Do this
        ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "registerInitializer", buildInitializer(), true);
    }
}

一旦渲染,“buildInitializer”逻辑会说,“如果这个函数存在于客户端......调用它。”而且...它每次都有效。

private string buildInitializer()
{
    StringBuilder javascript = new StringBuilder();

    javascript.Append("if (window.initializeMyControl) {");
    javascript.Append("if(typeof window.initializeMyControl == 'function') { initializeMyControl(); }");
    javascript.Append("}");

    return javascript.ToString();
}

现在您的用户控件初始化可以存在于用户控件中它应该在的位置:

<script type="text/javascript">
    function initializeMyControl() {

        // Your normal code goes here
        setupSomething();
        initializeSomethingElse();
    }
</script>

【讨论】:

  • +1 非常有帮助的答案,谢谢。在我实施了您的解决方案后,我看到了问题中的流行评论,并用更少的代码解决了我的问题:*.com/questions/1152946/…