什么';s异步加载小部件的最佳方式

本文关键字:小部 最佳 方式 加载 异步 什么 | 更新日期: 2023-09-27 18:19:54

我正试图为我公司的内部网站模拟iGoogle小部件,但我在回复时遇到了问题。我收到的错误是

Sys.WebForms.PageRequestManagerServerErrorException:Sys.WebForms.PageRequestManager服务器ErrorException:状态信息对此页面无效,可能已损坏。

单击LayoutButton1按钮时,我收到此错误。奇怪的是,这个错误发生在IE 9和Chrome 16上,但在Firefox 9中没有。

如何使用我的方法加载ASPX页面或用户控件?我是不是错过了什么?有更好的方法吗?

这里是我想要的行为:

1) 用户第一次点击页面,页面就会完全加载。每个小部件都显示一个ajax加载程序gif。2) 页面完全加载后,我对每个小部件进行异步调用以加载它们的内容。每个小部件的内容都包含ASP.NET服务器控件,如网格视图控件和树视图控件,因此小部件内容需要是用户控件或ASPX页面。在我的概念验证项目中,我使用ASPX页面。3) 在检索到小部件的内容后,ajax加载程序gif将替换为我从异步调用中收到的标记。

这是我正在使用的代码。请注意,我正在为小部件使用Telerik ASP.NET服务器控件(这不会对我的问题产生任何影响)。

<script type="text/javascript">
    $(document).ready(function ()
    {
        // Wires a client-side click event to the layout buttons.
        $('.layouts').find('input').live('click', function ()
        {
            if ($(this).attr('class') == 'layoutSelected')
            {
                return false;
            }
            else
            {
                return true;
            }
        });
    });
    // Load content of all widgets.
    function loadAllWidgets()
    {
        loadWidget1();
    }
    // Loads widget #1.
    function loadWidget1()
    {
        $(document).ready(function ()
        {
            PageMethods.LoadWidgetContent1(onWidgetContentLoadSucceeded, onWidgetContentLoadFailed);
        });
    }
    // Widget content load success.
    function onWidgetContentLoadSucceeded(result, userContext, methodName)
    {
        switch (methodName)
        {
            case "LoadWidgetContent1":
                $('#Widget1').find('.widgetContent').html(result);
                break;
        }
    }
    // Widget content load fail.
    function onWidgetContentLoadFailed(error, userContext, methodName)
    {
        alert(error);
    }
</script>
<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <div style="padding-bottom: 10px;">
            <table class="layouts">
                <tr>
                    <td>Layout:</td>
                    <td><asp:Button ID="LayoutButton1" CommandArgument="1" OnClick="LayoutButton_Click" runat="server" /></td>
                </tr>
            </table>
        </div>
        <div>
            <telerik:RadDockLayout ID="RadDockLayout1" runat="server">
                <telerik:RadDockZone ID="RadDockZone1" CssClass="dockZone dockZoneWide" runat="server" />
            </telerik:RadDockLayout>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>
protected void LayoutButton_Click(object sender, EventArgs e)
{
    var layoutNumber = Convert.ToInt32(((Button)sender).CommandArgument);
    switch (layoutNumber)
    {
        case 1:
            LayoutButton1.CssClass = "layoutSelected";
            LayoutButton2.CssClass = string.Empty;
            LayoutButton3.CssClass = string.Empty;
            LayoutButton4.CssClass = string.Empty;
            RadDockZone1.CssClass = "dockZone dockZoneWide";
            RadDockZone2.CssClass = "dockZone dockZoneNormal";
            RadDockZone3.CssClass = "dockZone dockZoneNormal";
            RadDockZone4.CssClass = "dockZone dockZoneNormal";
            RadDockZone5.CssClass = "dockZone dockZoneNormal";
            RadDockZone4.Visible = true;
            RadDockZone5.Visible = false;
            CreateWidgets();
            break;
    }
}
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        CreateWidgets();
    }
}
private void CreateWidgets()
{
    var radDock = new RadDock
    {
        Closed = false,
        DefaultCommands = DefaultCommands.All,
        ID = "Widget 1",
        Resizable = false,
        Skin = "Sitefinity",
        Title = "Widget 1",
    };
    var divTag = new HtmlGenericControl("div");
    divTag.Attributes.Add("class", "widgetContent");
    var image = new Image
    {
        CssClass = "ajaxLoader",
        ImageUrl = "~/images/transparent.gif",
        ToolTip = "loading..."
    };
    divTag.Controls.Add(image);
    radDock.ContentContainer.Controls.Add(divTag);
    RadDockLayout1.Controls.Add(radDock);
    radDock.Dock(RadDockZone1);

    ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "LoadAllWidgets", "loadAllWidgets();", true);
}
[WebMethod]
public static string LoadWidgetContent1()
{
    var stringWriter = new StringWriter();
    HttpContext.Current.Server.Execute("~/WidgetContent/WidgetContent1.aspx", stringWriter);
    return stringWriter.ToString();
}

什么';s异步加载小部件的最佳方式

OK-经过几个小时和多种方法,我认为我找到了一个好的解决方案。我发现可行的解决方案是使用用户控件而不是ASPX页面。这将允许使用服务器标记,并防止我遇到的无效视图状态问题。我需要在后面的代码中进行的唯一更改是更新web方法,如下所示:

[WebMethod]
public static string LoadWidgetContent()
{
    Page pageHolder = new Page();
    UserControl viewControl = (UserControl)pageHolder.LoadControl("~/WidgetContent/WidgetContent.ascx");
    pageHolder.Controls.Add(viewControl);
    StringWriter output = new StringWriter();
    HttpContext.Current.Server.Execute(pageHolder, output, false);
    return output.ToString();
}

这种方法允许我继续使用更新面板,并在页面完全加载后加载小部件。最后我用了顾的博客作为参考。这有点过时了,但使用web方法的基本原则仍然适用。

您使用的方法是正确的,并且可以工作。如果你需要一个专业小工具的例子,可以看看Telerik Sitefinity。该产品是商业产品,但您可以下载试用版并进行测试。