SignalR Update Panel Only Works First Time

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-24 12:37:32

问题


I have the following code inside of an update panel. When the screen loads, the SignalR code works fine. However, after the first time, once I click a button, the SignalR code does not fire anymore until I cause a redirect back to the page.

Basically what I am doing is when the user clicks the preview button, it fires off the reporting process. An Ajax modal popup is displayed with a progress indicator and a cancel button. If the user clicks the cancel button, the cancelation token is set, and the report is canceled. By using the SignalR technology, the ui thread is not blocked and the user can click the cancel button. This works fine the first time in. however, after clicking the cancel button, the next time when you click on the cancel button it does not work. However, when I redirect to the page again it works.

If I move the linkbutton outside of the update panel it works every time.

        <asp:updatepanel runat="server" id="UpdatePanelFooter" rendermode="Inline" updatemode="Conditional">                    
            <contenttemplate>
                  <table width="100%">
                    <tr>
                        <td>
                            <div id="divBottomBanner">
                                <asp:label id="LabelHelpID" runat="server" text="" visible="false"></asp:label>&nbsp;    
                                <asp:linkbutton id="LinkButtonPreview" runat="server" OnClick="LinkButtonPreview_Click">Preview</asp:linkbutton>  
                                <asp:linkbutton id="LinkButtonSaveAs" runat="server" onclick="LinkButtonSaveAs_Click">Save Prompts As</asp:linkbutton>
                                <asp:linkbutton id="LinkButtonGenerateSP" runat="server" onclick="LinkButtonGenerateSP_Click"><<<< GENERATE SP >>>></asp:linkbutton>
                                <asp:linkbutton id="LinkButtonInvisibleTargetControlIDSAVEAS" runat="server" causesvalidation="false" height="0" text="" width="0"></asp:linkbutton>
                                <asp:linkbutton id="LinkButtonInvisibleTargetControlIDPROGRESS" runat="server" causesvalidation="false" height="0" text="" width="0"></asp:linkbutton>
                            </div>
                        </td>
                    </tr>
                </table>
                    <ajaxtoolkit:modalpopupextender id="ModalPopupExtenderPROGRESS" runat="server" targetcontrolid="LinkButtonInvisibleTargetControlIDPROGRESS" behaviorid="PROGRESS" popupcontrolid="PanelPROGRESS" backgroundcssclass="ModalBackground" dropshadow="true">
                    </ajaxtoolkit:modalpopupextender>
                    <asp:panel id="PanelPROGRESS" runat="server" cssclass="ModalPopup" style="display: none;" width="75em">
                        <table id="TablePROGRESS" width="95%">
                            <tr>
                                <td style="width: 10%"></td>
                                <td style="width: 30%"></td>
                                <td style="width: 50%"></td>
                                <td style="width: 10%"></td>
                            </tr>
                            <tr>
                                <td></td>
                                <td colspan="2" align="center">Processing Please Wait
                                <br />
                                    <br />
                                    <hr />
                                </td>
                            </tr>
                            <tr>
                                <td></td>
                                <td colspan="2" align="center">
                                    <img src="../Images/moving_lights.gif" alt="Processing..." />
                                    <hr />
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <br />
                                    <br />
                                </td>
                            </tr>
                            <tr>
                                <td></td>
                                <td align="center" colspan="2">
                                    <asp:linkbutton id="LinkButtonCancelPROGRESSXD" runat="server" height="100%" cssclass="Button" causesvalidation="false" tabindex="6">&nbsp;&nbsp;&nbsp;Cancel Preview Report&nbsp;&nbsp;&nbsp;</asp:linkbutton>
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <br />
                                    <br />
                                </td>
                            </tr>
                        </table>
                    </asp:panel>
            </contenttemplate>
        </asp:updatepanel>

I then have the following code in the script that is used in the SignalR section.

/// <reference path="../scripts/jquery-1.8.3.js" />
/// <reference path="../scripts/jquery.signalR-1.0.0.js" />

/*!
    ASP.NET SignalR Report Processing
*/

// Crockford's supplant method 
if (!String.prototype.supplant) {
    String.prototype.supplant = function (o) {
        return this.replace(/{([^{}]*)}/g,
            function (a, b) {
                var r = o[b];
                return typeof r === 'string' || typeof r === 'number' ? r : a;
            }
        );
    };
}

// A simple background color flash effect that uses jQuery Color plugin
jQuery.fn.flash = function (color, duration) {
    var current = this.css('backgroundColor');
    this.animate({ backgroundColor: 'rgb(' + color + ')' }, duration / 2)
        .animate({ backgroundColor: current }, duration / 2);
}

$(function () {

    var RPT = $.connection.ReportProcessing;

    function stopRPT() {
        //$ReportProcessingUl.stop();
    }

    function init() {
        return RPT.server.waitForReportToBeReady().done(function () {
            //   Add Code Here
        });
    }

    //function jsFireThePreviewClick() {
    //    var ctrl = $("#ImageButtonRUNTHEREPORTXD");
    //    if (ctrl != null) {
    //        ctrl.click();
    //    }
    //}

    // Add client-side hub methods that the server will call
    $.extend(RPT.client, {
        updateReportProgress: function () {

        },

        ReportOpened: function () {
            //scrollRPT();
        },

        ReportClosed: function () {
            stopRPT();
        },

        ReportCancel: function () {
            return init();
        }
    });

    // Start the connection
    $.connection.hub.start()
        .pipe(init)
        .pipe(function () {
            return RPT.server.waitForReportToBeReady();
        })
        .done(function (state) {
            if (state === 'Open') {
                RPT.client.ReportOpened();
            } else {
                RPT.client.ReportClosed();
            }

            // Wire up the buttons
            $("#LinkButtonPreview").click(function () {
                RPT.server.openReport();
            });

            $("#close").click(function () {
                RPT.server.closeReport();
            });

            $("#LinkButtonCancelPROGRESSXD").click(function () {
                RPT.server.cancelReport();
                alert('Report Canceled By User');
            });
        });
});

If I move the LinkButtonPreview outside of the update panel, it works fine every time. I need to have this linkbutton inside of the update panel, but need it to work every time using the SignalR. I know it has something to do with the update panel and the way it handles the postback. However, I can not figure out what I need to do in order to get this to work correctly every time. Like I said, it does work the first time, but after that it does not.


回答1:


As you suspected, the issue is related to the update panel. You're adding a click event handler to the #LinkButtonPreview button, but that button element only exists until the update panel refreshes. When the update panel updates, a new button is created with the same id but without the event handler that was attached to the old button.

The solution is to attach your click event handler to an element that is never going to be updated/replaced so the event handler isn't ever removed. You can still have the event handler only respond #LinkButtonPreview clicks without attaching the event to #LinkButtonPreview directly using .on():

$(document).on("click", "#LinkButtonPreview", function(){
    RPT.server.openReport();
});

Since document is an ancestor element of #LinkButtonPreview, the click event originating from #LinkButtonPreview will bubble up all the way up to document. If you don't specify #LinkButtonPreview as the second argument to .on(), the event handler will be triggered by any click on the page.

You should also attach your click event handler the same way for #LinkButtonCancelPROGRESSXD.



来源:https://stackoverflow.com/questions/15675592/signalr-update-panel-only-works-first-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!