如何将Handsontable保存到数据库

问题描述:

是否有一种通用模式将数据保存到数据库中?如何将Handsontable保存到数据库

我正在使用ajax和WCF服务从我的数据库中提取数据来填充表。该服务正在返回表示数据库表中的一行数据的对象列表。

WCF:

<ServiceContract(Namespace:="")> 
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> 
Public Class TableService 

    <OperationContract()> 
    <WebGet(ResponseFormat:=WebMessageFormat.Json)> 
    Public Function GetResource() As List(Of Resource) 
     Dim conn = <some connection string> 
     Dim sql = <some SQL> 
     Dim dt = New DataTable("foo") 

     Using da As New SqlDataAdapter(sql, conn) 
      da.Fill(dt) 
     End Using 

     Return Objectify(dt) 
    End Function 

    Private Function Objectify(dt As DataTable) As List(Of Resource) 
     Dim resourceTable = New List(Of Resource) 

     For Each row As DataRow In dt.Rows 
      resourceTable.Add(New Resource With { 
       .ResourceAllocationID = row("ResourceAllocationID"), 
       .ResourceName = row("ResourceName"), 
       .AllocationPercent = row("AllocationPercent"), 
       .Month = row("Month"), 
       .Year = row("Year"), 
       .Comments = row("Comments"), 
       .ProjectID = row("ProjectID"), 
       .ResourceUId = row("ResourceUId")}) 
     Next 

     Return resourceTable 
    End Function 
End Class 

Public Class Resource 
    Public Property ResourceAllocationID As Integer 
    Public Property ResourceName As String 
    Public Property AllocationPercent As Integer 
    Public Property Month As String 
     Get 
      Return _monthName 
     End Get 
     Set(value As String) 
      Dim intMonth As Integer 
      If Integer.TryParse(value, intMonth) Then 
       If [Enum].IsDefined(GetType(MonthName), intMonth) Then 
        _monthName = CType(value, MonthName).ToString 
       End If 
      Else 
       If [Enum].IsDefined(GetType(MonthName), value) Then 
        _monthName = value 
       End If 
      End If 
     End Set 
    End Property   
    Public Property Year As Integer 
    Public Property Comments As String 
    Public Property ProjectID As Integer 
    Public Property ResourceUId As String 

    Private _monthName As String 

    Public Enum MonthName 
     January = 1 
     February = 2 
     March = 3 
     April = 4 
     May = 5 
     June = 6 
     July = 7 
     August = 8 
     September = 9 
     October = 10 
     November = 11 
     December = 12 
    End Enum 
End Class 

Javacript:

$("#container").handsontable({ 
    contextMenu: true, 
    startRows: 1, 
    minRows: 1, 
    colHeaders: ['Year', 'Month', 'Name', '% Allocation', 'Comments'], 
    colWidths: [52, 100, 150, 100, 200], 
    columns: [ 
     { data: 'Year', type: 'numeric' }, 
     { data: 'Month' }, 
     { data: 'ResourceName' }, 
     { data: 'AllocationPercent', type: 'numeric' }, 
     { data: 'Comments' } 
    ] 
}); 

$.ajax({ 
    url: "TableService.svc/GetResource", 
    type: "GET", 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    success: function (data) { 
     $("#container").handsontable(loadData, data.d) 
    }, 
    error: function (error) { 
     alert("Error: " + error); 
    } 
}); 

这精美的作品来填充表。我正在努力的是如何将更改保存回数据库。要求不是保存任何更改,直到所有更改完成并点击更新按钮。

我知道我可以通过调用handsontable.getData()得到一个包含表中所有单元的对象。我在想的是我需要将对象序列化到Json中,将它发送回我的服务,将它反序列化为对象列表,然后为列表中的每个对象更新数据库。我在正确的轨道上吗?如果是这样,我该如何实际执行它?

所以,我最终拼凑出一个解决方案,以满足我的具体要求。

我首先需要得到一个JSON格式的字符串,它表示Handsontable的所有单元格传回我的WCF服务。方法handsontable.getData()返回表示表中所有数据的对象。然后,我使用JSON.stringify()将该对象转换为字符串。从那里我无法将该字符串传递给我的服务。我最终发现我必须对已经字符串化的对象进行串联处理,以便为我的服务创建适当的字符串参数,同时正确地转义对象中的引号。

$("#btnUpdate").click(function() { 
    var tableData = JSON.stringify(handsontable.getData()); 
    var input = JSON.stringify({ "input": tableData }); 

    $.ajax({ 
     type: 'POST', 
     url: "TableService.svc/SaveResource", 
     data: input, 
     contentType: "application/json; charset=utf-8", 
     dataType: 'json', 
     success: function (res) { 
      if (res.result === 'ok') { 
       console.text('Data saved'); 
      } 
     }, 
     error: function (xhr) { 
      alert(xhr.responseText); 
     } 
    }); 
    $("btnUpdate").blur(); 
}); 

现在我的表数据返回服务器端,我需要将JSON解析回对象列表。我结束了使用JSON.NET来完成这一点。一旦我有一个对象列表,我将每个列表项添加为一个新的DataTable中的一行,我可以在其中运行必要的SQL来更新数据库。

<OperationContract()> 
<WebInvoke(Method:="POST", BodyStyle:=WebMessageBodyStyle.WrappedRequest, ResponseFormat:=WebMessageFormat.Json)> 
Public Function SaveResource(ByVal input As String) As String 
    Dim resources As List(Of Resource) = Json.JsonConvert.DeserializeObject(Of List(Of Resource))(input) 
    UpdateDB(resources) 
    Return "ok" 
End Function 

Private Sub UpdateDB(resources As List(Of Resource)) 
    Dim dt As New DataTable 
    Dim conn = <some connection string> 
    Dim sql = <some SQL> 
    Using da As New SqlDataAdapter(sql, conn) 
     da.FillSchema(dt, SchemaType.Source) 
     For Each resourceItem In resources 
      Dim row As DataRow = dt.NewRow() 
      Dim month As Resource.MonthName 
      row("ResourceAllocationID") = resourceItem.ResourceAllocationID 
      row("ResourceName") = resourceItem.ResourceName 
      row("AllocationPercent") = resourceItem.AllocationPercent 
      row("Month") = [Enum].TryParse(resourceItem.Month, month) 
      row("Year") = resourceItem.Year 
      row("Comments") = resourceItem.Comments 
      row("ProjectID") = resourceItem.ProjectID 
      row("ResourceUId") = resourceItem.ResourceUId 
      dt.Rows.Add(row) 
     Next 
    End Using 
    *<run the appropriate SQL on each row of dt to update the database>* 
End Sub 
+0

这与我想出的处理从ASP.NET WebForms项目中保存数据的解决方案完全相同。做得好! – itanex 2014-02-22 07:50:59

有两种方法可以处理这个:

  1. 小编辑收集数据,保存到本地浏览器,当用户点击保存发送数据的编辑块回数据库。

  2. 保留数据表的本地版本,对其进行编辑,当用户点击保存时,将整个表格发回并保存到数据库中。

我会使用方法1,因为它会减少流失,并且不会意外覆盖。你会想要使用onChange callback。我认为你需要有一个隐藏的列,其中包含你正在编辑的行的ID。

# coffeescript 
onChangeHandler = -> 
    rowChange = rowID: theDataArray[arguments[0]], rowCol: arguments[1], newVal: arguments[3], dateTime: new Date() 
    window.MyNamespace.edits.push(rowChange) 

tableDiv.handsontable 
    ... 
    onChange: onChangeHandler 

$('#save').click(-> 
# save data back to the database 
) 
+0

感谢您花时间回复@jcollum,但我需要回答的问题实际上是关于如何将数据返回到数据库。对不起,如果我没有在原来的文章中说清楚。我实际上已经提出了一个解决方案,并且会在明天发布。 – jtrohde 2013-05-12 17:00:32