-2

わかりました。問題があります。私は現在、ASP.NET AJAX用のTelerikフレームワークを使用してプロジェクトに取り組んでいますが、作業のこの部分ではTelerikを完全に(ほぼ)バイパスしているので、それはそれほど重要ではありません。

私はFacebookのようなチャットプログラムを当社のCRMシステムにまとめています。これまでのところすべてが順調に進んでいますが、障害にぶつかっています。問題は、「新しいチャットボックスを作成」しようとしたときです。aspコントロールのUpdatePanelをjQuery$.ajax呼び出しと組み合わせて使用​​して、JSONメソッド名をコードビハインドファイルに渡します。JSONロジックは次のとおりです。

ユーザーリストのユーザーのDoubleClick:

$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"); }
            });
        }

asyncpostbackを強制します(必要ではないはずですが、これも機能しません!):

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

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

UpdatePanelは、さまざまなリテラルとハードコードされたhtmlgood-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を持ちません。
4

1 に答える 1

1

ご担当者様


さて、投稿した翌日にたまたまこの問題を解決しました。もちろん、今や取り組むべき新しいハードルがありますが、非同期チャットモジュールはほぼ完成していると言って嬉しいです。誰も問題を引き受けることに決めなかったので、ASP.NETでハードコードされたHTMLに基づいて動的な非同期オブジェクトを適切に生成するために行ったことを投稿します。問題をグーグルしながら、この投稿がポップアップする唯一の関連する結果だったからです。 。

私はこれが非常に型破りなアプローチであることをよく知っていると言うことから始めます。そうは言っても、プロジェクトの要件は手段を正当化した。あなたの目標を達成するために他の多くの方法があるかもしれませんが、これはうまくいきます。私の特定のプロジェクトに関して余計な詳細に立ち入るつもりはありませんが、これが将来誰かに役立つことを願っています。

Wrongs


私の最初の質問の主な問題は、レンダリングシーケンスを攻撃する方法でした。私のロジックの主な欠陥は、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);

その意味


私が行ったのは、チャットボックス要素全体を単一のプレースホルダー内にラップし、サーバーからすべてのASPコントロールをラップするHTML要素を動的に作成し、動的データの「チャンク」として投稿することだけです。これにより、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をチェックしておりますので、お気軽に質問(または懸念事項)を投稿してください。

于 2013-03-28T19:37:41.080 に答える