簡體   English   中英

什么是異步加載小部件的最佳方法?

[英]What's The Best Way To Load Widgets Asynchronously?

我正在嘗試為我公司的內部網站模擬iGoogle小部件,當我回帖時我遇到了問題。 我收到的錯誤是

Sys.WebForms.PageRequestManagerServerErrorException:Sys.WebForms.PageRequestManagerServerErrorException:狀態信息對於此頁面無效,可能已損壞。

單擊LayoutButton1按鈕時收到此錯誤。 奇怪的是,這個錯誤發生在IE 9和Chrome 16上,但不是在Firefox 9中。

如何使用我的方法加載ASPX頁面或用戶控件? 我錯過了什么嗎? 有沒有更好的方法呢?

這是我想要的行為:

1)用戶第一次點擊頁面並完全加載頁面。 每個小部件都顯示一個ajax loader gif。 2)頁面完全加載后,我為每個小部件進行異步調用以加載其內容。 每個窗口小部件的內容包含ASP.NET服務器控件,如網格視圖控件和樹視圖控件,因此窗口小部件內容需要是用戶控件或ASPX頁面。 在我的概念驗證項目中,我正在使用ASPX頁面。 3)在檢索小部件的內容之后,將ajax loader 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();
}

好的 - 經過幾個小時和多個方法,我想我找到了一個很好的解決方案。 我發現工作的解決方案是使用用戶控件而不是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();
}

這種方法允許我繼續使用更新面板並在頁面完全加載后加載小部件。 我最終使用Scott Gu的博客作為參考 這有點過時,但使用Web方法的基本原則仍然存在。

您使用的方法是正確的,可以工作。 如果您需要專業小部件的示例 - 請查看Telerik Sitefinity。 該產品是商業版,但您可以下載試用版並進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM