ASP.NET-Postback mit JavaScript

80

Ich habe mehrere kleine divs, die jQueryziehbar verwenden. Diese divs werden in einem platziert UpdatePanelund beim Dragstop verwende ich die _doPostBack()JavaScript-Funktion, mit der ich die erforderlichen Informationen aus dem Formular der Seite extrahiere.

Mein Problem ist, dass beim Aufrufen dieser Funktion die gesamte Seite neu geladen wird, ich jedoch nur möchte, dass das Update-Panel neu geladen wird.

ErnieStings
quelle
Haben Ihre Divs alle eine eindeutige ID?
Nathan Taylor

Antworten:

226

Hier ist eine Komplettlösung

Gesamtes Formular-Tag der asp.net-Seite

<form id="form1" runat="server">
    <asp:LinkButton ID="LinkButton1" runat="server" /> <%-- included to force __doPostBack javascript function to be rendered --%>

    <input type="button" id="Button45" name="Button45" onclick="javascript:__doPostBack('ButtonA','')" value="clicking this will run ButtonA.Click Event Handler" /><br /><br />
    <input type="button" id="Button46" name="Button46" onclick="javascript:__doPostBack('ButtonB','')" value="clicking this will run ButtonB.Click Event Handler" /><br /><br />

    <asp:Button runat="server" ID="ButtonA" ClientIDMode="Static" Text="ButtonA" /><br /><br />
    <asp:Button runat="server" ID="ButtonB" ClientIDMode="Static" Text="ButtonB" />
</form>

Gesamter Inhalt der Code-Behind-Klasse der Seite

Private Sub ButtonA_Click(sender As Object, e As System.EventArgs) Handles ButtonA.Click
    Response.Write("You ran the ButtonA click event")
End Sub

Private Sub ButtonB_Click(sender As Object, e As System.EventArgs) Handles ButtonB.Click
    Response.Write("You ran the ButtonB click event")
End Sub
  • Der LinkButton ist enthalten, um sicherzustellen, dass die Javascript-Funktion __doPostBack für den Client gerendert wird. Wenn Sie nur Button-Steuerelemente haben, wird diese __doPostBack-Funktion nicht gerendert. Diese Funktion wird aufgrund einer Vielzahl von Steuerelementen auf den meisten ASP.NET-Seiten gerendert, sodass normalerweise keine leere Linkschaltfläche erforderlich ist

Was ist los?

Für den Client werden zwei Eingabesteuerelemente gerendert:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
  • __EVENTTARGET erhält Argument 1 von __doPostBack
  • __EVENTARGUMENT erhält Argument 2 von __doPostBack

Die __doPostBack-Funktion wird folgendermaßen gerendert:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
  • Wie Sie sehen können, werden die Werte den versteckten Eingaben zugewiesen.

Wenn das Formular gesendet / zurückgesendet wird:

  • Wenn Sie die UniqueID der Server-Steuerungsschaltfläche angegeben haben, deren Schaltflächenklick-Handler Sie ausführen möchten ( javascript:__doPostBack('ButtonB','')dann wird der Schaltflächenklick-Handler für diese Schaltfläche ausgeführt.

Was ist, wenn ich keinen Klick-Handler ausführen möchte, sondern stattdessen etwas anderes tun möchte?

Sie können alles, was Sie wollen, als Argumente übergeben __doPostBack

Sie können dann die versteckten Eingabewerte analysieren und spezifischen Code entsprechend ausführen:

If Request.Form("__EVENTTARGET") = "DoSomethingElse" Then
    Response.Write("Do Something else") 
End If

Weitere Hinweise

  • Was ist, wenn ich die ID des Steuerelements nicht kenne, dessen Klick-Handler ich ausführen möchte?
    • Wenn das Einstellen nicht akzeptabel ist ClientIDMode="Static", können Sie Folgendes tun : __doPostBack('<%= myclientid.UniqueID %>', '').
    • Oder: __doPostBack('<%= MYBUTTON.UniqueID %>','')
    • Dadurch wird die eindeutige ID des Steuerelements in das Javascript eingefügt, falls Sie dies wünschen
Brian Webster
quelle
47
+1 für die Vollständigkeit. Eine Art großartiger Antworten, die mich dazu bringen, StackOverflow zu lieben.
Manitra Andriamitondra
3
Dies ist eine der besten Erklärungen, die ich je für __doPostBack () gefunden habe. +10 dafür!
GuruC
1
@BrianWebster, vielen Dank für deinen ausführlichen Beitrag. Könnte ich jedem vorschlagen, der noch mit ASP.NET 3.5 und niedriger C # anstelle von VB.NET verwendet und die letzten beiden Zeilen in der ASPX-Datei wie folgt ändert? <asp: Button runat = "Server" ID = "ButtonA" Text = "ButtonA" OnClick = "ButtonA_Click" /> <br /> <br /> <asp: Button runat = "Server" ID = "ButtonB" Text = "ButtonB" OnClick = "ButtonB_Click" />
yangli.liy
1
Dies ist eine sehr hilfreiche Lösung. Wenn Sie Masterseiten verwenden, wird die ID der Schaltflächen etwas verschleiert. In der Antwort von user489998 unten finden Sie Hilfe beim Abrufen der richtigen ID für das Postback.
DCastenholz
1
@BrianWebster Es ist wirklich selten, dass jemand in der Lage ist, eine vollständige Lösung für das Problem einer Person bereitzustellen UND geeignete Alternativen zu möglichen Abweichungen bereitzustellen.
GoldBishop
15

Per Phairoh: Verwenden Sie diese Option auf der Seite / Komponente, falls sich der Panel-Name ändert

<script type="text/javascript">
     <!--
     //must be global to be called by ExternalInterface
         function JSFunction() {
             __doPostBack('<%= myUpdatePanel.ClientID  %>', '');
         }
     -->
     </script>
Laramie
quelle
9

Während Phairohs Lösung theoretisch fundiert erscheint, habe ich auch eine andere Lösung für dieses Problem gefunden. Durch Übergeben der UpdatePanels-ID als Parameter (Ereignisziel) für die doPostBack-Funktion wird das Update-Panel zurückgesendet, jedoch nicht die gesamte Seite.

__doPostBack('myUpdatePanelId','')

* Hinweis: Der zweite Parameter dient zum Hinzufügen von Ereignisargumenten

hoffe das hilft jemandem!

EDIT: so scheint es, dass der gleiche Rat oben gegeben wurde, als ich tippte :)

ErnieStings
quelle
2
Dies wird funktionieren, und ich habe in einer Anwendung etwas Ähnliches getan, aber es ist wirklich keine gute Idee, und ich hasse es, dass ich es tun musste, als ich es tat. Wenn sich der Name Ihres Update-Panels jemals ändert, wird er unterbrochen. Wenn Sie dies jemals in ein Benutzersteuerelement einfügen, wird es unterbrochen. Wenn Sie eine Masterseite hinzufügen, wird diese unterbrochen. Ja, es funktioniert, aber es ist ziemlich zerbrechlich. Verwenden Sie mindestens die ClientId-Eigenschaft Ihres Update-Panels anstelle der statischen Zeichenfolge.
Phairoh
7

Mit __doPostBackdirekt ist sooooo die 2000er Jahre. Jeder, der 2018 WebForms codiert, verwendet GetPostBackEventReference

(Im Ernst, das Hinzufügen als Antwort der Vollständigkeit halber. Die __doPostBackdirekte Verwendung ist eine schlechte Praxis (ein einfacher Unterstrich zeigt normalerweise ein privates Mitglied an und ein doppeltes ein universelleres privates Mitglied), obwohl es sich wahrscheinlich nicht ändert oder veraltet Punkt. Wir haben einen vollständig unterstützten Mechanismus in ClientScriptManager.GetPostBackEventReference .)

Angenommen, Ihr btnRefresh befindet sich in unserem UpdatePanel und verursacht ein Postback. Sie können GetPostBackEventReference wie folgt verwenden ( Inspiration ):

function RefreshGrid() {
    <%= ClientScript.GetPostBackEventReference(btnRefresh, String.Empty) %>;
}
mlhDev
quelle
Das funktioniert sehr gut. In meiner Situation kann ich deklarieren, dass die Target AJAX-Steuerelemente aktualisiert werden, wenn im HTML-Markup auf btnRefresh geklickt wird. Auf diese Weise war es äußerst einfach, dies mit Unterstützung für AJAX zu implementieren.
DanielG
6

Wenn jemand Probleme damit hat (wie ich), können Sie den Postback-Code für eine Schaltfläche erhalten, indem Sie das Attribut UseSubmitBehavior = "false" hinzufügen. Wenn Sie die gerenderte Quelle der Schaltfläche untersuchen, sehen Sie genau das Javascript, das Sie ausführen müssen. In meinem Fall wurde eher der Name der Schaltfläche als die ID verwendet.

user489998
quelle
Sehr hilfreich bei der Verwendung von Masterseiten.
DCastenholz
1
__doPostBack scheint bei der Verwendung von Masterseiten immer den Namen der Schaltfläche zu verwenden.
Dennis T - Wiedereinstellung Monica -
2

Haben Sie versucht, die Client-ID des Update-Panels an die Funktion __doPostBack zu übergeben? Mein Team hat dies getan, um ein Update-Panel zu aktualisieren, und soweit ich weiß, hat es funktioniert.

__doPostBack(UpdatePanelClientID, '**Some String**');
Jeremy Bade
quelle
1

Verwenden Sie zunächst keine Update-Panels. Sie sind die zweitbeste Sache, die Microsoft jemals für den Webentwickler erstellt hat.

Zweitens, wenn Sie müssen Update Panels verwenden, versuchen Sie die Updatemode- Eigenschaft auf Bedingte Einstellung. Fügen Sie dann einem Asp: Hidden-Steuerelement, das Sie der Seite hinzufügen, einen Auslöser hinzu. Weisen Sie das Änderungsereignis als Auslöser zu. Ändern Sie in Ihrem Dragstop-Ereignis den Wert des ausgeblendeten Steuerelements.

Dies ist ungetestet, aber die Theorie scheint stichhaltig zu sein ... Wenn dies nicht funktioniert, können Sie dasselbe mit einer asp: -Schaltfläche versuchen. Stellen Sie einfach die Anzeige ein: keinen Stil darauf und verwenden Sie das Klickereignis anstelle des Änderungsereignisses.

Phairoh
quelle
7
Was ist das erste Übel, das Microsoft für Webentwickler erstellt hat?
ErnieStings
2
Die Anmeldesteuerung muss ganz oben auf dieser Liste stehen.
Kim3er
27
@ErnieStings: IE6
Phairoh
1
Können Sie eine Erklärung geben, was UpdatePanels so böse macht? Wenn es so ist, würde ich gerne einige Gründe lesen, warum und wann man sie nicht benutzt. Bisher bin ich auf keine entscheidenden Probleme mit UpdatePanels gestoßen.
Jan Kukacka
@ JanKukacka Sie sind eine schlechte Abstraktion von AJAX. Die Fähigkeiten, die Sie beim Schreiben von Update-Panels erlernen, führen nicht direkt dazu, dass AJAX auch außerhalb von ASP.NET Web Forms ordnungsgemäß verwendet werden kann. UpdatePanels sind schwer zu debuggen. Wenn Sie ViewState aktiviert haben, wird eine große Datenmenge unnötig zum / vom Server übertragen, wodurch die Bandbreite intensiv wird. Das Erlernen von AJAX (möglicherweise mit einer einfachen Abstraktionsschicht wie jQuery) ist eine weitaus bessere Lösung, wenn Sie mit dem Server sprechen müssen, ohne ein Postback durchzuführen.
Maurer
1

Sie können nicht aufrufen, _doPostBack()da dies das Einreichen des Formulars erzwingt. Warum deaktivierst du das nicht PostBackauf dem UpdatePanel?

Alex Rodrigues
quelle
1
Eine Frage. Wenn ein div gezogen wird, wird das _doPostBack von Ihnen oder automatisch von ASP.NET aufgerufen?
Alex Rodrigues
es wird von mir über Javascript
aufgerufen