2013-04-30 389 views
1

是否有一種通用模式將數據保存到數據庫中?如何將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中,將它發送回我的服務,將它反序列化爲對象列表,然後爲列表中的每個對象更新數據庫。我在正確的軌道上嗎?如果是這樣,我該如何實際執行它?

回答

3

所以,我最終拼湊出一個解決方案,以滿足我的具體要求。

我首先需要得到一個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

2

有兩種方法可以處理這個:

  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