jQuery填充的Gridview在回发时丢失数据

Posted

技术标签:

【中文标题】jQuery填充的Gridview在回发时丢失数据【英文标题】:jQuery populated Gridview losing data on postback 【发布时间】:2018-09-01 01:04:09 【问题描述】:

我有一个使用 javascript (jQuery) 填充客户端的 gridview,我需要在回发时将数据发送到服务器。显然,客户端处理的任何数据在正常回发时都会丢失,因此需要寻找在回发时保留客户端数据的最佳方法。

我的每月付款计划的 jQuery 代码(完美运行):

totalmonths = moment(paymentbydate).diff(today, 'month');
var totalamount = ((amountdue / totalmonths) + ((amountdue / totalmonths) * processingfee));

var weeklyamount = toFixed(amountdue / totalmonths, 2);
var paymentprocessingfee = toFixed((amountdue / totalmonths) * processingfee, 2);
var lastpayment = 0;
totalamount = toFixed(parseFloat(weeklyamount) + parseFloat(paymentprocessingfee), 2); //(amountdue/totalweeks) + ((amountdue / totalweeks) * processingfee);

// Add first payment to grid
$("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + todaydate + "</td><td>" + weeklyamount + "</td><td>" + paymentprocessingfee + "</td><td>" + totalamount + "</td></tr>");
// Add second payment, startdate, to grid
var nextdate = moment(datevalue, 'MM/DD/YYYY').add(1, 'months').format('MM/DD/YYYY');
$("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + datevalue + "</td><td>" + weeklyamount + "</td><td>" + paymentprocessingfee + "</td><td>" + totalamount + "</td></tr>");

var totalpaymentsmade = parseFloat(totalamount) * 2;
// Total up payment so you can calculate overage/underpayment if any
// add all subsequet payments until paid in full
for (i = 0; i < (totalmonths - 2) ; i++) 
    totalpaymentsmade = totalpaymentsmade + parseFloat(totalamount); // Total up the next payment
    var nextpayment  = toFixed(totalpaymentsmade - amountduewithfee, 2);
    if (nextpayment == 0) 
        $("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + nextdate + "</td><td>Final Payment: " + weeklyamount + "</td><td>" + paymentprocessingfee + "</td><td>" + totalamount + "</td></tr>");
        break;
     else 
        $("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + nextdate + "</td><td>" + weeklyamount + "</td><td>" + paymentprocessingfee + "</td><td>" + totalamount + "</td></tr>");
    
    nextdate = moment(nextdate, 'MM/DD/YYYY').add(1, 'months').format('MM/DD/YYYY');
    numpayments += 1;
    // check if next payment is overpayment or underpayment but under payment amount
    lastpayment = toFixed(amountduewithfee - totalpaymentsmade, 2);
    if (totalpaymentsmade > amountduewithfee) 
        $("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + nextdate + "</td><td>Final Payment</td><td>0</td><td>" + lastpayment + "</td></tr>");
        break;
     else if ((amountduewithfee - totalpaymentsmade) < amountduewithfee && (amountduewithfee - totalpaymentsmade) < totalamount) 
        $("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + nextdate + "</td><td>Final Payment</td><td>0</td><td>" + lastpayment + "</td></tr>");
        break;
     else if (totalpaymentsmade == amountduewithfee) 
        $("#<%=GridView_PaymentSchedule.ClientID%>").append("<tr><td>" + nextdate + "</td><td>Final Payment</td><td>0</td><td>" + lastpayment + "</td></tr>");
        break;
    

更新: 经过一些研究,似乎处理这种情况的最佳方法是使用 ajax 通过我所做的 web 方法将数据发布到服务器,但现在当我使用字符串数组数组调用该方法时,它执行时没有错误但是服务器端没有收到数据,我得到一个空列表。

我的 ajax 调用:

$.ajax(
    type: "POST",
    url: "PaymentPlan.aspx/SaveGridViewData",
    data: 'pPayments: ' + JSON.stringify( payments: payments ) + '',
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    traditional: true,
    success: function (response) 
    alert("Data sucessfully transmited.");
        window.location.reload();
    ,
    error: function (response) 
        alert("Data not transmited: error = " + response.responseText);
    
);

payments 是一个数组数组,[date,amount,fee,total],所有字符串都是为了让事情变得简单。

后面的代码: 我保持简单,我在x += 1 上放了一个断点来检查参数。

<WebMethod()> _
Public Shared Sub SaveGridViewData(ByVal pPayments As List(Of String()))
    Dim x As Integer
    x += 1
End Sub

结果是 pPayments 是一个空列表,我试过pPayments as List(of string),结果相同。我还尝试使用四个属性和一个无参数构造函数和一个带参数的构造函数创建一个支付类,我得到no parameterless constructor defined for this object。显然我不明白这个问题。有人有什么建议吗?

【问题讨论】:

服务器不知道您用数据填充了 GridVIew,因此当您执行 PostBack 时,所有更改都会丢失。如果要访问该数据,必须首先在后面的代码中填充 GridView,或者将数据存储在 HiddenField 中,然后将其发送到服务器并在那里进行处理。 谢谢,但不知道需要支付的总次数使得隐藏字段难以使用,而且,我不喜欢隐藏字段......在我看来它很乱,只是我的意见....寻找更多“优雅”的选择。 我不知道源数据来自哪里,但是您可以在代码中执行 ajax Web 请求并将其绑定到 GridView。 数据是在客户端生成的,它来自“nowhere”。客户端选择付款间隔,并在 javascript (jQuery) 中生成数量、日期、开始日期和付款金额,因此在页面加载或任何其他事件中没有任何绑定。 【参考方案1】:

好的,我想通了。我改变了构造 JSON 对象的方式,而不是数组数组,而是构造对象数组:

jQuery (ajax) 代码:

var thepayment = new Array();

// Pull the data out of the gridview
$('[id*=GridView_PaymentSchedule]').find('tr:has(td)').each(function () 
    var obj = new Object;
    obj.paymentdate = $(this).find('td').eq(0)[0].innerhtml;
    obj.amount = $(this).find('td').eq(1)[0].innerHTML;
    obj.processingfee = $(this).find('td').eq(2)[0].innerHTML;
    obj.totalamount = $(this).find('td').eq(3)[0].innerHTML;

    thepayment.push(obj);
);

// This is the line of code that made the difference
// DTO stands for Data Transfer Object
// Then you JSON stringify it, not all at once.

// This DOES NOT work:
// 'pPayments: ' + JSON.stringify( payments: thepayment ) + ''

// This does:
var DTO =  'pPayments': thepayment ;

$.ajax(
    type: "POST",
    url: "PaymentPlan.aspx/SaveGridViewData",
    data: JSON.stringify(DTO), // 'pPayments: ' + JSON.stringify( payments: thepayment ) + '',
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    traditional: true,
    success: function (response) 
        alert("Data sucessfully transmited.");
        window.location.reload();
    ,
    error: function (response) 
        alert("Data not transmited: error = " + response.responseText);
    

);

支付类:

Public Class payments
    Public Sub New()
        MyClass.New("", "", "", "")
    End Sub
    Public Sub New(ByVal pPaymentdate As String, ByVal pAmount As String, ByVal pProcessingfee As String, ByVal pTotalamount As String)
        paymendate = pPaymentdate
        amount = pAmount
        processingfee = pProcessingfee
        totalamount = pTotalamount
    End Sub

    Public Property paymendate As String

    Public Property amount As String

    Public Property processingfee As String

    Public Property totalamount As String

End Class

网络方式:

<WebMethod()> _
Public Shared Sub SaveGridViewData(ByVal pPayments As List(Of payments))
    ' Do Stuff
End Sub

【讨论】:

以上是关于jQuery填充的Gridview在回发时丢失数据的主要内容,如果未能解决你的问题,请参考以下文章

列表框在回发时重复(重复)

DropDownList 中的 ListItems 属性在回发时丢失?

GridView 在回发或 onselectedindexchanged 后丢失数据表页眉和页脚

如何避免在回发时从 asp.net 重复输入?

从支付网关回发时丢失会话

由 javascript 更改时回发时丢失的值