【问题标题】:ASP.NET AJAX UpdatePanel & Dynamic HTML Insertion Issue (Telerik)ASP.NET AJAX UpdatePanel 和动态 HTML 插入问题 (Telerik)
【发布时间】:2013-03-22 14:24:09
【问题描述】:

好的,我有一个问题。我目前正在开发一个使用 ASP.NET AJAX 的 Telerik 框架的项目,尽管这并不重要,因为我在这部分工作中完全(几乎)绕过了 Telerik。

我正在将一个类似于 facebook 的聊天程序整合到我们公司的 CRM 系统中,虽然到目前为止一切顺利,但我遇到了障碍。问题是当我尝试“创建一个新的聊天框”时。我将 asp 控件 UpdatePanel 与 jQuery $.ajax 调用结合使用,将 JSON 方法名称传递给我的代码隐藏文件。这是 JSON 逻辑:

双击用户列表中的用户:

$telerik.$(".UserListEntry").dblclick(function () {
                var ToName = $telerik.$(this).children(".UserListEntryName").text();
                var FromName = $telerik.$("#lkUserGeneralSettings").text();
                $telerik.$.ajax({
                    type: 'POST',
                    url: 'DefaultHandler.ashx',
                    data: { "ToName": ToName, "FromName": FromName },
                    success: CreateChatBox(),
                    error: function (response) { alert("error: 001"); }
                });
            });

CreateChatBox 回调:

function CreateChatBox() {
            $telerik.$.ajax({
                type: 'POST',
                url: 'Default.aspx',
                data: { MethodName: "CreateChatBox" },
                success: ForceAsyncPostback,
                error: function (response) { alert("error: 002"); }
            });
        }

强制异步回发(应该没有必要,但这甚至也不起作用!):

function ForceAsyncPostback() {
            var UpdatePanel1 = '<%=Panel3.ClientID%>';

            if (UpdatePanel1 != null) {
                __doPostBack(UpdatePanel1, '');
            }
            alert("Success");
        }

UpdatePanel 是通过各种文字和一些硬编码的 html good-ole' 风格的 div 创建的。问题是 动态创建所述元素,这工作得很好。事实上,如果我将其放入我的 PageLoad 事件中,我的代码(我将在下面发布)创建并显示一切都非常好。

无论如何,这是 .aspx:

<asp:UpdatePanel ID="Panel3" runat="server" OnLoad="Panel3_Load" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Literal ID="ChatBoxesLiteralTop" runat="server" />
                    <asp:Literal ID="ChatBoxesLiteralMid" runat="server" />
                    <asp:PlaceHolder ID="ChatBoxesPlaceHolder" runat="server" />
                    <asp:Literal ID="ChatBoxesLiteralBot" runat="server" />
                    <div id="UserListCorner">
                        <img id="UserListBtn" src="images/list.png" />
                    </div>
                    <div id="UserList" class="UserListHidden">
                        <div id="UserListView">
                            <asp:Literal ID="UserListViewLiteral" runat="server" />
                        </div>
                    </div>
                </ContentTemplate>
            </asp:UpdatePanel>

代码隐藏:

protected void Panel3_Load(object sender, EventArgs e)
    {
        #region Ajax methods
        if (Request.Form["MethodName"] == "CreateChatBox")
        {
            CreateChatBox();
        }
        #endregion

        Engine m_engine = new Engine();
        string m_sql = @"SELECT FullName FROM Users WHERE RecordDeleted <> 1";
        DataTable dt = m_engine.GetObjectsAsDataTable(m_sql);
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            UserListViewLiteral.Text += "<div class='UserListEntry'><span class='UserListEntryStatus'><img src='images/status-online.png' width='10' /></span>&nbsp;<span class='UserListEntryName'>" + dt.Rows[i]["FullName"].ToString() + "</span></div>";
        }

        RadAjaxManager.GetCurrent(Page).ResponseScripts.Add("ChatAjax()");   
    }

    private void CreateChatBox()
    {
        ChatBoxesLiteralTop.Text = @"<div id='ChatBox' class='ChatBoxHidden'>
                                        <div class='ChatBoxHeader'>
                                            <img id='ChatBoxStatusBtn' src='Images/status-online.png' />
                                            <span id='ChatBoxUserLabel'>John Doe</span>
                                            <img id='closeBtn' src='Images/close.png' />
                                            <img id='toggleTab' src='Images/up-arrow.png' />
                                        </div>
                                        <div id='ChatBoxMessageOutput'></div><div class='ChatBoxFooter'>";

        TextBox txt = new TextBox();
        txt.ID = "ChatBoxMessageInput";
        txt.Height = 16;
        txt.MaxLength = 270;
        txt.Width = 250;
        txt.AutoPostBack = false;
        ChatBoxesPlaceHolder.Controls.Add(txt);

        RadButton btn = new RadButton();
        btn.ID = "ChatBoxSendButton";
        btn.Text = "Send";
        btn.AutoPostBack = true;
        btn.Height = 22;
        btn.Click += ChatBoxSendButton_Click;
        ChatBoxesPlaceHolder.Controls.Add(btn);

        ChatBoxesLiteralBot.Text = "</div></div>";

        Panel3.Update();

        RadAjaxManager.GetCurrent(Page).ResponseScripts.Add("ChatAjax()");
    }

我当然忽略了一些非常愚蠢的事情,但如果有经验丰富的 ASP.Net Ajaxer 提供的全新视角,我将不胜感激!提前致谢。

问题说明

有什么作用:

  • 代码运行正常。
  • JSON 方法被传递给后面的代码并被读取。
  • CreateChatBox() 方法贯穿并据称填充了文字和控件。
  • JSON 链中的所有回调均已成功执行。

什么不起作用:

  • 即使在冗余回发之后,UpdatePanel 也没有 代码成功执行后的这个新 HTML。

【问题讨论】:

  • 您对这篇文章没有任何疑问。你说“问题是当我尝试创建一个新的聊天框时”。什么问题???
  • 对不起,我已经澄清了上面的问题

标签: c# asp.net json telerik asp.net-ajax


【解决方案1】:

可能关注的对象


好吧,我恰好在发布后的第二天就解决了这个问题。当然,现在有新的障碍需要解决,但我很高兴地说我的异步聊天模块快完成了。由于没有人决定解决这个问题,我将发布我为正确生成基于 ASP.NET 中硬编码 HTML 的动态异步对象所做的工作,因为在谷歌搜索此事时,这篇文章是唯一弹出的相关结果.

我首先要说我很清楚这是一种非常规的方法。话虽如此,项目的要求证明了手段的合理性。虽然可能有许多其他方法可以实现您的目标,但这确实有效。对于我的特定项目,我不打算详细介绍无关的细节,但希望这对将来的人有所帮助。

错误


我最初的问题的主要问题是我攻击渲染序列的方式。我的逻辑中的一个主要缺陷是试图将 ASP 控件(文字、占位符、按钮等)与我的 HTML 分离太多。我最初的方法(从上面)看起来像这样:

<asp:UpdatePanel ID="Panel3" runat="server" OnLoad="Panel3_Load" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:Literal ID="ChatBoxesLiteralTop" runat="server" />
                <asp:Literal ID="ChatBoxesLiteralMid" runat="server" />
                <asp:PlaceHolder ID="ChatBoxesPlaceHolder" runat="server" />
                <asp:Literal ID="ChatBoxesLiteralBot" runat="server" />
                <div id="UserListCorner">
                    <img id="UserListBtn" src="images/list.png" />
                </div>
                <div id="UserList" class="UserListHidden">
                    <div id="UserListView">
                        <asp:Literal ID="UserListViewLiteral" runat="server" />
                    </div>
                </div>
            </ContentTemplate>
</asp:UpdatePanel>

最终的结果看起来更像这样:

<asp:UpdatePanel ID="Panel3" runat="server" OnLoad="Panel3_Load" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:PlaceHolder ID="ChatBoxesPlaceHolder" runat="server" />
                    <div id="UserListCorner">
                        <img id="UserListBtn" src="images/list.png" />
                    </div>
                    <div id="UserList" class="UserListHidden">
                        <div id="UserListView">
                            <asp:Literal ID="UserListViewLiteral" runat="server" />
                        </div>
                    </div>
                    <asp:Label ID="Label42" Font-Bold="true" runat="server" />
                    <asp:HiddenField runat="server" ID="LatestDisplayTick" />
                </ContentTemplate>
</asp:UpdatePanel>

后面的代码(删节)与此类似:

Literal top = new Literal();
// ...
UpdatePanel UpdatePanel2 = new UpdatePanel();
// ...
top.Text = @"<div id='ChatBox' class='ChatBoxShown'>
                                             <div class='ChatBoxHeader'>
                                                 <img id='ChatBoxStatusBtn' src='Images/status-online.png' />
                                                 <span id='ChatBoxUserLabel'>" + UserNames[0] + @"</span>
                                                 <img id='closeBtn' src='Images/close.png' />
                                                 <img id='toggleTab' src='Images/up-arrow.png' />
                                             </div>";

top.ID = "ChatBoxesLiteralTop";
top.Mode = LiteralMode.PassThrough;
// ...
UpdatePanel2.ID = "UpdatePanel2";
UpdatePanel2.UpdateMode = UpdatePanelUpdateMode.Conditional;
UpdatePanel2.ChildrenAsTriggers = false;
UpdatePanel2.ContentTemplateContainer.Controls.Add(top2);
// ...
Panel3.ContentTemplateContainer.Controls.Add(top);
Panel3.ContentTemplateContainer.Controls.Add(UpdatePanel2);               
Panel3.ContentTemplateContainer.Controls.Add(mid);

这是什么意思


我所做的只是将整个聊天框元素包装在一个占位符中,动态创建 HTML 元素,将所有来自服务器的 ASP 控件包装起来,并将其作为动态数据的“块”发布。这避免了 ASP 控件放置的一些奇怪行为,并允许为我的项目的客户端功能使用准 OO 方法。创建后,我现在可以使用一些 JSON 和 AJAX 调用将数据动态输入到动态创建的控件中。

例如,将从数据库通知接收到的消息发布到我的聊天窗口(ChatBoxesLiteralMid 控件)。

页面/控件加载后

if(ChatBoxesLiteralMid != null)
            ChatBoxesLiteralMid.Text += @"<div class='ChatBoxEntry'><span class='ChatBoxEntryName ChatBoxSelf'>" + AppParameters.Current.AppUser.FirstName + "</span>:&nbsp;<span class='ChatBoxEntryMessage'>" + dy.Rows[dy.Rows.Count - 1]["Message"].ToString() + "</span></div>";

为什么要惹上麻烦?


我所完成的是一个需要远远超出原始范围的特定项目,该项目是几年前由另一位开发人员开始的。这是教老狗一些新技巧的非常规方式。我现在几乎可以完全控制客户端上任意数量的实时聊天框/会话。老实说,这真的很甜。请随时发布问题(或疑虑),因为我会定期检查 SO 并很乐意回复。

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多