【问题标题】:Async Postback with Listview not workingListview 的异步回发不起作用
【发布时间】:2015-03-13 15:49:53
【问题描述】:

我有一个包含许多链接按钮的列表视图。目前,当您单击一个按钮时,它会触发一个完整的回发,我想交换它以便它只是部分回发。似乎它应该足够简单,但无论我做什么,我似乎都无法让它工作。似乎我错过了一些明显的东西,但在这一点上,我很难过。

列表视图:

<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" ChildrenAsTriggers="False" runat="server">
<ContentTemplate>
  <section id="basketbox">
    <hgroup class="mainhead">
      <h2>Your basket</h2>
    </hgroup>
    <asp:ListView runat="server" ID="ListView1" OnItemCommand="ListView1_ItemCommand" DataSourceID="SqlDataSource1" DataKeyNames="PartCode">
      <LayoutTemplate>
          <div runat="server" id="itemPlaceholder" ></div>
      </LayoutTemplate>
      <ItemTemplate>
            <h4><%#Eval("Name") %></h4>
            <div class="quantitybox">
              <div class="qtylbl">Qty</div>
              <asp:LinkButton id="QtyDown" CommandArgument='<%#Databinder.Eval(Container.DataItem,"PartCode")%>' CssClass="qtybutton" CommandName="QtyDown" runat="server"><img src="/images/minus.png"></asp:LinkButton>
              <div class="qtybox"><%#Eval("Quantity") %></div>
              <asp:LinkButton id="QtyUp" CommandArgument='<%#Databinder.Eval(Container.DataItem,"PartCode")%>' CssClass="qtybutton" CommandName="QtyUp" runat="server"><img src="/images/plus.png"></asp:LinkButton>
            </div>
      </ItemTemplate>
    </asp:ListView>
  </section>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="ListView1" />
</Triggers>
</asp:UpdatePanel>

我尝试过的事情: -ChildrenAsTriggers 设置为 true(没有区别)

-将触发器设置为链接按钮 ID(未找到控件)

-在页面声明中将页面设置为异步(没有区别)

-在列表视图控件上将 ClientIDMode 设置为 AutoID(没有区别)

-向脚本管理器注册一个链接按钮(下面的代码隐藏函数)

Private Sub RegisterPostBackControl()
    For Each item As ListviewItem In  ListView1.Items
        Dim lnkFull As LinkButton = TryCast(item.FindControl("QtyUp"), LinkButton)
        ScriptManager.GetCurrent(Me).RegisterAsyncPostBackControl(lnkFull)
    Next
End Sub

再次:没有区别

我也尝试了其中的大多数组合在一起;这些都没有任何区别。

我还应该尝试什么?

【问题讨论】:

  • Setting the page to be async in the page declaration (made no difference) 这与 UpdatePanel 完全无关,这是为了支持异步/等待。 -Setting ClientIDMode to AutoID on the listview control (made no difference) 客户端上的 ID 无关紧要。您是否尝试过将每个 LinkBut​​ton 包装在它自己的 UpdatePanel 中?顺便说一句,我建议你完全放弃 UpdatePanel (because it's bad),只使用 AJAX 和 Web API
  • @mason 我知道 UpdatePanels 是魔鬼的产物 - 不幸的是,我正在从事的项目的截止日期太近了,我无法离开并为此掌握 Web API。我还没有尝试嵌套更新面板 - 我会试一试。 (感谢您的解释——它们都是我在扯掉头发后以“它可能有什么帮助”为基础尝试的东西)
  • 您没有必须使用 Web API,尤其是因为它仅适用于 .NET 4.5(但它是理想的)。我也不推荐 ASMX,因为该服务基本上已被弃用。如果我是你,我会设置一些通用处理程序 (.ashx)。让他们履行 Web API 中控制器的职责。你不会得到很好的模型绑定的东西,你需要手动从查询字符串/表单值中提取值。但这一切都应该简单快捷地实施。我知道只使用 UpdatePanel 来“完成”的诱惑,但您大概必须支持此代码,对吧?
  • @Mason 是的,我确实必须支持代码 - 这是另一个原因,至少在这一点上,我宁愿不必学习一批全新的编码只是为了支持这个项目的这一页! (此外,当我说截止日期紧迫时,我的意思是它有望在下周中旬上线。)
  • 嵌套更新面板没有帮助(作为一个附带问题,它们也破坏了我的布局!)

标签: asp.net vb.net listview


【解决方案1】:

您的 cmets 听起来您需要学习很多才能使用通用处理程序来响应 AJAX 请求。不是这样的,你可能有必要的知识

QtyDown.ashx

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;

public class QtyChangeResponse
{
    public bool Success {get; set;}
    public string Message {get; set;}
}

public class Handler : IHttpHandler
{
    public void ProcessRequest (HttpContext context)
    {
        //pull values from query string
        //update database based on values
        //create response
        var responseObj = new QtyChangeResponse(){Success=true, Message="Qty Updated"};
        context.Response.ContentType="application/json";
        context.Response.Write(JsonConvert.SerializeObject(responseObj));       
    }

    public bool IsReusable
    { get { return false; } }
}

VB版(Telerik自动翻译)

Imports System.Web

Public Class QtyChangeResponse
    Public Property Success() As Boolean
        Get
            Return m_Success
        End Get
        Set
            m_Success = Value
        End Set
    End Property
    Private m_Success As Boolean
    Public Property Message() As String
        Get
            Return m_Message
        End Get
        Set
            m_Message = Value
        End Set
    End Property
    Private m_Message As String
End Class

Public Class Handler
    Implements IHttpHandler
    Public Sub ProcessRequest(context As HttpContext)
        'pull values from query string
        'update database based on values
        'create response
        Dim responseObj = New QtyChangeResponse() With { _
            Key .Success = True, _
            Key .Message = "Qty Updated" _
        }
        context.Response.ContentType = "application/json"
        context.Response.Write(JsonConvert.SerializeObject(responseObj))
    End Sub

    Public ReadOnly Property IsReusable() As Boolean
        Get
            Return False
        End Get
    End Property
End Class

所以这与 Web API 控制器大致相同。

<asp:LinkButton id="QtyDown" CssClass="qtybutton" runat="server" OnClientClick='QtyDown(<%#Databinder.Eval(Container.DataItem,"PartCode")%>); return false;'><img src="/images/minus.png"></asp:LinkButton>

<script type="text/javascript">
function QtyDown(partCode){
    //use your favorite JavaScript library to gather the quantity and PartCode and make a POST call to QtyDown.ashx?qty={quantity}&partcode={partcode)
}
</script>

比 UpdatePanel 更容易支持,错误更少,而且我已经为你做了很多工作。

【讨论】:

  • 1) 老实说,我可能有很多东西要学——我对 .net 的了解不完整,而且大部分是自学的(因此不可避免的愚蠢问题)2) 不幸的是,我使用 vb.net 所以一个 c# 解决方案真的对我没有帮助
  • @FrustratedWDotNet C# 和 VB 非常接近,以至于存在可以完成合理工作的代码转换器。我已经使用了其中之一,并使用等效的 VB 代码更新了我的答案。不,如果您可以处理来自 Web 表单页面的回发并更新数据库,那么您可以从通用处理程序中执行相同的操作。您需要的唯一额外知识是 JavaScript。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多