使用 JavaScript 的 ASP.NET 回发

Posted

技术标签:

【中文标题】使用 JavaScript 的 ASP.NET 回发【英文标题】:ASP.NET postback with JavaScript 【发布时间】:2010-11-21 07:32:53 【问题描述】:

我有几个小的divs 正在使用jQuery 可拖动。这些divs 被放置在UpdatePanel 中,在dragstop 上我使用_doPostBack() javascript 函数,从页面表单中提取必要的信息。

我的问题是,当我调用这个函数时,整个页面被重新加载,但我只想重新加载更新面板。

【问题讨论】:

你的 div 都有唯一的 ID 吗? 【参考方案1】:

这里有一个完整的解决方案

asp.net页面的整个表单标签

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

页面代码隐藏类的全部内容

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
包含 LinkBut​​ton 是为了确保将 __doPostBack javascript 函数呈现给客户端。简单地拥有 Button 控件不会导致此 __doPostBack 函数被呈现。此功能将通过在大多数 ASP.NET 页面上具有各种控件来呈现,因此通常不需要空链接按钮

发生了什么事?

两个输入控件呈现给客户端:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
__EVENTTARGET 接收 __doPostBack 的参数 1 __EVENTARGUMENT 接收 __doPostBack 的参数 2

__doPostBack 函数呈现如下:

function __doPostBack(eventTarget, eventArgument) 
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) 
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    

如您所见,它将值分配给隐藏的输入。

当表单提交/回发发生时:

如果您提供了要运行其按钮单击处理程序的服务器控制按钮的唯一 ID (javascript:__doPostBack('ButtonB',''),则将运行该按钮的按钮单击处理程序。

如果我不想运行点击处理程序,而是想执行其他操作怎么办?

你可以将任何你想要的作为参数传递给__doPostBack

然后您可以分析隐藏的输入值并相应地运行特定代码:

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

其他说明

如果我不知道要运行其单击处理程序的控件的 ID 怎么办? 如果设置ClientIDMode="Static" 是不可接受的,那么您可以执行以下操作:__doPostBack('&lt;%= myclientid.UniqueID %&gt;', '')。 或:__doPostBack('&lt;%= MYBUTTON.UniqueID %&gt;','') 如果您愿意,这会将控件的唯一 ID 注入到 javascript 中

【讨论】:

+1 表示完整性。一些很棒的答案让我喜欢 ***。 这是我遇到过的对 __doPostBack() 最好的解释之一。为此 +10! @BrianWebster,非常感谢您的详细帖子。我是否可以建议仍然使用 ASP.NET 3.5 及以下版本的人使用 C# 而不是 VB.NET 将 .aspx 文件中的最后两行更改为如下? 这是一个非常有用的解决方案。如果您使用的是母版页,按钮的 id 会有点模糊。请参阅下面的 user489998 的答案,以帮助获取回发的正确 ID。 @BrianWebster 很少有人能够为某人的问题提供完整的解决方案并为潜在的偏差提供适当的替代方案。【参考方案2】:

Per Phairoh:在页面/组件中使用它,以防面板名称发生变化

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

【讨论】:

【参考方案3】:

虽然 Phairoh 的解决方案在理论上似乎是合理的,但我也找到了解决此问题的另一种解决方案。通过将 UpdatePanels id 作为 doPostBack 函数的参数(事件目标)传递,更新面板将回发而不是整个页面。

__doPostBack('myUpdatePanelId','')

*注意:第二个参数用于添加事件参数

希望这对某人有帮助!

编辑:所以在我输入时,上面似乎给出了同样的建议:)

【讨论】:

这行得通,我在应用程序中做了类似的事情,但这真的不是一个好主意,我讨厌我必须这样做。如果您的更新面板的名称发生变化,它就会中断。如果你把它放在用户控件中,它就会中断。如果添加母版页,它会中断。是的,它有效,但它非常脆弱。至少,请使用更新面板的 ClientId 属性而不是静态字符串。【参考方案4】:

直接使用__doPostBack 是2000 年代。 2018 年任何编写 WebForms 的人都会使用 GetPostBackEventReference

(更严重的是,将其添加为完整性的答案。直接使用__doPostBack 是不好的做法(单下划线前缀通常表示私有成员,双下划线表示更通用的私有成员),尽管它可能不会此时会更改或过时。我们在ClientScriptManager.GetPostBackEventReference 中有完全支持的机制。)

假设您的 btnRefresh 在我们的 UpdatePanel 中并导致回发,您可以像这样使用 GetPostBackEventReference (inspiration):

function RefreshGrid() 
    <%= ClientScript.GetPostBackEventReference(btnRefresh, String.Empty) %>;

【讨论】:

这很好用。在我的情况下,我可以在 html 标记中单击 btnRefresh 时声明要刷新的目标 AJAX 控件。通过使用它,在支持 AJAX 的情况下实现它变得非常简单。【参考方案5】:

如果有人遇到了这个问题(就像我一样),您可以通过向按钮添加 UseSubmitBehavior="false" 属性来获取按钮的回发代码。如果您检查按钮的呈现源,您将看到您需要执行的确切 javascript。在我的例子中,它使用的是按钮的名称而不是 id。

【讨论】:

在使用母版页时非常有帮助。 __doPostBack 在使用母版页时似乎总是使用按钮的名称。【参考方案6】:

您是否尝试过将更新面板的客户端 ID 传递给 __doPostBack 函数?我的团队这样做是为了刷新更新面板,据我所知它确实有效。

__doPostBack(UpdatePanelClientID, '**Some String**');

【讨论】:

【参考方案7】:

首先,不要使用更新面板。它们是微软为 Web 开发人员创造的第二个最邪恶的东西。

其次,如果您必须使用更新面板,请尝试将 UpdateMode 属性设置为 Conditional。然后将触发器添加到您添加到页面的 Asp:Hidden 控件。将更改事件分配为触发器。在您的 dragstop 事件中,更改隐藏控件的值。

这是未经测试的,但理论似乎是合理的...如果这不起作用,您可以尝试使用 asp:button 做同样的事情,只需在其上设置 display:none 样式并使用点击事件而不是更改事件。

【讨论】:

微软为 Web 开发人员创造的第一个最邪恶的东西是什么? 登录控件必须在该列表中非常靠前。 你能解释一下是什么让 UpdatePanels 如此邪恶吗?如果是这样,我想阅读一些为什么以及何时不使用它们的原因。到目前为止,我还没有发现 UpdatePanels 的任何关键问题。 @JanKukacka 他们对 AJAX 的抽象很差。您在编写更新面板中学到的技能并不能直接转化为能够在 ASP.NET Web 窗体之外的任何东西中正确使用 AJAX。 UpdatePanel 很难调试。如果你打开了 ViewState,大量的数据会不必要地传入/传出服务器,从而占用大量带宽。当您需要在不执行回发的情况下与服务器通信时,学习正确的 AJAX(可能使用一些轻量级的抽象层,例如 jQuery)是一个更好的解决方案。【参考方案8】:

您不能调用_doPostBack(),因为它会强制提交表单。为什么不禁用UpdatePanel 上的PostBack

【讨论】:

一个问题。拖动 div 时,_doPostBack 是由您调用还是由 ASP.NET 自动调用? 它是我通过javascript调用的

以上是关于使用 JavaScript 的 ASP.NET 回发的主要内容,如果未能解决你的问题,请参考以下文章

自动发布回asp.net后如何重新加载脚本?

使用 javascript 禁用 asp.net 单选按钮

通过调用 ASP.NET 按钮单击从 jQuery 模态对话框回发

在asp.net anypostback之前做一些javascript

ASP.NET 在嵌套在更新面板中的用户控件中注入 javascript

UpdatePanel 异步回发后的 Javascript 事件订阅