Панель обновления SignalR работает только в первый раз

У меня есть следующий код внутри панели обновления. Когда экран загружается, код SignalR работает нормально. Однако после первого раза, когда я нажимаю кнопку, код SignalR больше не срабатывает, пока я не вызову перенаправление обратно на страницу.

В основном то, что я делаю, это когда пользователь нажимает кнопку предварительного просмотра, он запускает процесс отчетности. Отображается модальное всплывающее окно Ajax с индикатором выполнения и кнопкой отмены. Если пользователь нажимает кнопку отмены, маркер отмены устанавливается и отчет отменяется. При использовании технологии SignalR поток пользовательского интерфейса не блокируется, и пользователь может нажать кнопку отмены. Это отлично работает в первый раз. Однако после нажатия кнопки отмены в следующий раз, когда вы нажмете кнопку отмены, это не сработает. Однако, когда я снова перенаправляюсь на страницу, она работает.

Если я перемещаю кнопку ссылки за пределы панели обновления, она работает каждый раз.

        <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>

Затем у меня есть следующий код в сценарии, который используется в разделе SignalR.

/// <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');
            });
        });
});

Если я перемещаю LinkButtonPreview за пределы панели обновления, он каждый раз работает нормально. Мне нужно, чтобы эта кнопка ссылки находилась внутри панели обновления, но мне нужно, чтобы она работала каждый раз при использовании SignalR. Я знаю, что это как-то связано с панелью обновлений и тем, как она обрабатывает обратную передачу. Однако я не могу понять, что мне нужно сделать, чтобы это работало правильно каждый раз. Как я уже сказал, это работает в первый раз, но после этого это не так.


person Bruce Pullum    schedule 28.03.2013    source источник


Ответы (1)


Как вы подозревали, проблема связана с панелью обновлений. Вы добавляете обработчик события клика к кнопке #LinkButtonPreview, но этот элемент кнопки существует только до тех пор, пока панель обновления не обновится. При обновлении панели обновления создается новая кнопка с тем же идентификатором, но без обработчика событий, который был прикреплен к старой кнопке.

Решение состоит в том, чтобы прикрепить обработчик событий щелчка к элементу, который никогда не будет обновляться/заменяться, чтобы обработчик событий никогда не удалялся. Вы по-прежнему можете заставить обработчик событий реагировать только на #LinkButtonPreview кликов, не связывая событие с #LinkButtonPreview напрямую, используя .on():

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

Поскольку document является предком элемента #LinkButtonPreview, событие click, происходящее из #LinkButtonPreview, будет всплывать вплоть до document. Если вы не укажете #LinkButtonPreview в качестве второго аргумента .on(), обработчик событий будет запускаться при любом щелчке на странице.

Вы также должны прикрепить свой обработчик события клика таким же образом для #LinkButtonCancelPROGRESSXD.

person halter73    schedule 28.03.2013
comment
Спасибо ... Вы спасаете жизнь ... :) Ценю ваше объяснение и пример .. - person Bruce Pullum; 28.03.2013