ASP.NET problēma ar AutoPostBack

Diemžēl sastapta kārtējā problēma ASP.NET iekšienē, kam būtu jābūt ļoti plaši izplatītai, tik nez kāpēc Microsoft nav uzskatījis par vajadzīgu to labot. Arī Connect sistēmā neatrodu, ka kas līdzīgs ir reģistrēts (būs jāpacenšas, taču nedomāju, ka tas ko mainīs).

Lai problēmu atkārtotu, var izveidot šādu lapu:

<asp:ScriptManager runat="server" EnablePartialRendering="true" />
<asp:UpdatePanel runat="server" UpdateMode="Always">
    <ContentTemplate>
        <asp:TextBox runat="server" ID="txt" AutoPostBack="true" />
        <asp:Button runat="server" ID="btn" Text="Submit" OnClick="Button_Click" />
        <asp:Label runat="server" ID="lbl" />
    </ContentTemplate>
</asp:UpdatePanel>

protected void Page_Load(object sender, EventArgs e)
{
    this.lbl.Text = this.Request["__EVENTTARGET"] == "txt" ? "textbox" : "other";
}

protected void Button_Click(object sender, EventArgs e)
{
    this.lbl.Text = "submit";
}

Problēma attiecas ne tikai uz ASP.NET Ajax, bet arī uz parastu ASP.NET lapu bez ScriptManager un UpdatePanel, taču tad tā parasti nav pamanāma, ja vien lapas apstrādē ir kaut neliela aizture.

Ja izmaina teksta lauka vērtību, tā tiek automātiski nosūtīta uz serveri un tas atgriež vērtību “textbox”. Savukārt, ja tiek nospiests uz pogas, tad serveris atgriež vērtību “submit”. Problēma slēpjas apstāklī, ka lietotājs, izmainot teksta lauka vērtību un uzreiz spiežot uz pogas, sagaida, ka tiks apstrādāta pogas nospiešana (piemēram, saglabāti dati). Šī brīža ASP.NET implementācijā tā nenotiek – uz serveri tiek nosūtīts AutoPostBack pieprasījums, bet lietotāja nospiestā poga paliek bez efekta. Ir pat tā, ka uz serveri reizēm var tikt nosūtīti abi divi, taču lietotājs redz, ka izpildās tikai viens.

Piedāvāju savu risinājumu (apkārtceļu) šai problēmai. Tam ir vairāki mīnusi, piemēram, ja no teksta lauka iziet ar Tab taustiņa palīdzību, uzreiz nonākot uz pogas, tad AutoPostBack nenostrādās (lai gan reāli uz pogas nospiests netiek). Tāpat to var apiet, nospiežot uz pogas un tad nobīdot peli nost, lai pogas klikšķis nenostrādā.

function shouldAbortRequest(eventTarget) {
    if (document.activeElement && document.activeElement.id != eventTarget
        && (document.activeElement.id || document.getElementById(eventTarget))) {
        var tagName = document.activeElement.tagName.toLowerCase();
        var type;
        if (tagName == "input")
            type = document.activeElement.type.toLowerCase();
        if (type == "submit" || type == "button" || tagName == "button" || tagName == "a")
            return true;
    }
    return false;
}

window.original__doPostBack = __doPostBack;
window.__doPostBack = function (eventTarget, eventArgument) {
    if (shouldAbortRequest(eventTarget))
        return;
    window.original__doPostBack(eventTarget, eventArgument);
};

Dotais JavaScript kods (jāievieto lapas beigās) aizvieto ASP.NET iebūvēto __doPostBack metodi, kas tiek izsaukta AutoPostBack gadījumā. Jaunā funkcija pārbauda, vai lietotājs nav nofokusējies uz kādu pogu un, ja tā ir, atceļ AutoPostBack pieprasījumu. Diemžēl tas nav ideāls risinājums, bet šobrīd vienīgais, kas lietotāju glābj no nepatīkamas situācijas, kur viņš ir nospiedis saglabāšanas pogu, bet reāli nekas saglabāts netiek.

Comments are closed