3

我和丹尼尔在这个主题中遇到了同样的问题,但他的解决方案对我不起作用:

http://www.kendoui.c​​om/forums/ui/grid/kendo-ui-grid-inserts-updates-create-duplicate-records.aspx#-jhxqRrNAUGsTFJaC-Ojwg

所以用例。用户依次添加2条新记录:

  1. 按网格的“添加新记录”按钮
  2. 填写字段(name="Alex",amount=10,comment="first")。
  3. 记录一已准备就绪。按“保存”。(数据进入控制器而不是数据库)
  4. 用户在网格中看到一条记录

  5. 再次按“添加新记录”按钮

  6. 填写字段(name="Bob",amount=20,comment = "second")。
  7. 记录一已准备就绪。按“保存”。数据进入控制器而不是数据库。在这一刻发生了一些事情,网格再次发送 Ajax 请求并记录一个数据到控制器。

  8. 用户更新网格并看到三个记录

    “Alex | 10 | first”(重复记录)ID = 1

    “鲍勃 | 20 | 秒” ID = 2

    “亚历克斯 | 10 | 第一个” ID = 1

他们建议返回一个 ID,以便使用新记录正确绑定\更新数据源。然后我返回它(来自数据库的新 ID 以 bouns 实体作为响应)!这没有帮助。仅当我使用 F5 添加第一条记录并刷新页面,然后添加第二条记录时,一切正常。但是如果再添加一个,第三条记录-问题又出现了

控制器中的代码:

[HttpPost]
    public JsonResult Create(BonusDto bonusDto)
    {
        BonusAggregate bonus;

        if (bonusDto.Amount <= 0)
            throw new ArgumentOutOfRangeException("Amount should be more than 0");

        if (bonusDto.EmployeeId <= 0)
            throw new ArgumentNullException("You should specify an existing employee");

        using (var dbContext = new DatabaseContext())
        {
            BonusesRepository = new BonusesRepository(dbContext);
            var employeeRepository = new EmployeesRepository(dbContext);
            bonus = new BonusFactory(employeeRepository).Create(bonusDto);

            BonusesRepository.Save(bonus);
        }

        HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;
        return Json(bonus); // try to return ID after bonus was saved
    }

用户界面代码

// creates bonuses grid control
$("#bonusesGrid").kendoGrid({
    dataSource: bonusesDataSource,
    toolbar: ["create"],
    editable: "inline",
    columns: [
        "BonusId",
        "EmployeeId",
        {
            field: "EmployeeLastName",
            editor: employeeAutocompletingEditor,
            template: "#=EmployeeLastName#"
        },
        "Amount",
        {
            field: "Comment",
            titel: "Comment",
            editor: textareaEditor,
            filterable: {
                operators: {
                    number: {
                        contains: "Contains"
                    }
                }
            }
        },
        {
            command: ["edit"],
            title: " "
        }
    ],
    save: function(e) {
        if (newValueEmployeeId !== undefined && 
                            newValueEmployeeLastName !== undefined && 
                            newValueEmployeeLastName !== "") {
                              setNewValueEmployeeIdAndLastName(newValueEmployeeId, newValueEmployeeLastName);
                              gridDataSource.model.EmployeeId = newValueEmployeeId; // it's a hack to bind model and autocomplete control
                              gridDataSource.model.EmployeeLastName = newValueEmployeeLastName;
                        } else {
                              gridDataSource.model.EmployeeId = currentValueEmployeeId;
                              gridDataSource.model.EmployeeLastName = currentValueEmployeeLastName;

                        }
    },
    edit: function(e) {
        setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
    },
    cancel: function(e) {
        setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
    }
});

奖金数据来源:

// bind json result from /Bonuses/GetPagedJsonBonuses
        var bonusesDataSource = new kendo.data.DataSource({
                transport: {

                    read: {
                         url: "@Url.Action("GetPagedJsonBonuses", "Bonuses")",
                         type : "GET",
                         contentType: "application/json",
                         dataType: "json",
                         cache: false
                    },
                    create: {
                        url: "@Url.Action("Create", "Bonuses")",
                        dataType: "json",
                        type: "POST"
                    },
                    parameterMap: function(options, operation) {
                        if (operation === "update" || operation === "create") {

                            // correct format for conversion 
                            var d = new Date(options.Date);
                            options.Date = kendo.toString(d, dateFormat);

                            // updates the BonusDTO.EmployeeId with selected value
                            if (newValueEmployeeId !== undefined)
                                options.EmployeeId = newValueEmployeeId;
                        }
                        if(operation === "read") {
                            options.filter = setFormattedFilterDate(options.filter);
                        }
                        return options;
                    }
                },
                pageSize: 15,
                serverPaging: true,
                serverSorting: true,
                serverFiltering: true,
                error: showErrorMessage,
                schema: {
                    data: "Data", // PagedResponse.Data
                    total: "TotalCount", // PagedResponse.TotalCount
                    model: {
                        id: "BonusId",  // Data
                        fields: {
                            EmployeeId: { type: "number" },
                            EmployeeLastName: {
                                type: "string",
                                editable: true,
                                nulable: false,
                                validation: { required: {message: "Employee's last name is required"}}
                            },
                            Date: {
                                type: "date",
                                editable: true,
                                nullable: false,
                                validation: {
                                    required: { message: "Date is required to be set" }
                                }
                            },
                            Amount: {
                                type: "number",
                                editable: true,
                                nullable: false,
                                defaultValue: 1,
                                validation: {
                                    required: { message: "Amount is required to be set" }
                                }
                            },
                            Comment: { type: "string", editable: true }
                        } // fields
                    } // model
                }// schema 
            });
4

8 回答 8

11

我的代码中没有看到这个问题。但是,我在刷新网格的创建和更新事件上确实有一个“完整”事件处理程序 - 它可能会帮助您:

  dataSource: {

    type: "jsonp",
    transport: {
        read: UrlBase + "getAll",
        update: {
            url: UrlBase + "Update",
            dataType: "jsonp",
            complete: function (e) {
                $("#grid").data("kendoGrid").dataSource.read();

            }
        },
        create: {
            url: UrlBase + "create",
            dataType: "jsonp",
            complete: function (e) {
                $("#grid").data("kendoGrid").dataSource.read();
            }
        },
        destroy: {
            url: UrlBase + "destroy",
            dataType: "jsonp",
            complete: function (e) {
                $("#grid").data("kendoGrid").dataSource.read();
            }
        }
    },
   ...
于 2013-05-04T11:49:00.800 回答
6

是的,hamed 是正确的。您的“创建”操作结果会传入模型中要保存到数据库中的对象。让数据访问层中的 INSERT 返回数据库中新创建的键(“ID”)。现在使用此键设置模型上的“ID”字段,该字段已传递到操作结果,然后作为 JSON 传递回视图。现在网格应该知道它刚刚创建了这个记录,不需要对它做更多的事情。否则,模型对象返回时“ID”字段设置为 0,因此网格认为它仍然需要添加此记录。

[AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Grid_Create([DataSourceRequest] DataSourceRequest request, MyObject obj)
    {
        if (obj != null && ModelState.IsValid)
        {
            obj.Id = _myService.Create(obj);
        }

        return Json(new[] { obj }.ToDataSourceResult(request, ModelState));
    }
于 2014-06-16T13:38:33.603 回答
3

当您没有将主键传递给在读取操作中查看时,会发生此错误。

问候

于 2014-02-04T12:21:41.873 回答
2

Quinton Bernhardt 的完整事件的替代方法:将 dataSource.read() 绑定到 kendo 同步事件。

我正在使用不公开同步事件的 kendo 的 C# MVC 的 html 助手,因此我必须在设置网格后对其进行修改。

在窗口加载时:

var grid = $("#GridName").data("kendoGrid");
grid.dataSource.bind("sync", function () {
     $("#GridName").data("kendoGrid").dataSource.read();
});

保存请求完成后触发同步事件。从服务器获取最新的dataSource.read(),包括在服务器端设置的 id。

于 2014-09-24T16:50:18.787 回答
2

我有一个类似的问题,做了各种试验,但通过以下试验修复

jQuery

   create: {
                type: "POST",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                url: "../../ajax/ajaxGv.aspx/addstaff"
            },

            parameterMap: function (options, operation) {
                if (operation == "create" && options.models) {  
                    return JSON.stringify({ "oStaff": options.models });
                }

VB.Net

   'Adding Staff
   <System.Web.Services.WebMethod()> _
 Public Shared Sub addStaff(ByVal oStaff As Object)
    Dim strJson As String = JsonConvert.SerializeObject(oStaff)
    Dim lstStaff As List(Of Staff) = JsonConvert.DeserializeObject(Of List(Of Staff))(strJson)
    Dim db As New LiveB2cDataContext
    Try

            db.Staff.InsertAllOnSubmit(lstStaff)
        Next
        db.SubmitChanges()

      'Fix is that you need to return the objects you have added in the database back as json to kendo

        strJson = JsonConvert.SerializeObject(lstStaff, Formatting.None)
        WriteJson(strJson) ' Returning the objects added as json back to Kendo
    Catch ex As Exception
        ErrorLog(ex)
    End Try

End Sub

Public Shared Sub WriteJson(strJson As String)
    Try

        HttpContext.Current.Response.Write(strJson)
        HttpContext.Current.Response.Flush()
        HttpContext.Current.ApplicationInstance.CompleteRequest()
        HttpContext.Current.Response.SuppressContent = True

    Catch ex As Exception
        ErrorLog(ex)
    End Try
End Sub

Fix is that you need to return the objects you have added in the database back as json to kendo

于 2015-06-17T10:38:16.030 回答
0

我遇到了一个类似的问题。

我修复了它,但确保模型中的 id 是指一个字段:-

model: {
      id: "Id",
      fields: {
           Id: { editable: false, type: "number" },
           AnotherName: { editable: true, type: "string" },
           AnotherId: { editable: true, type: "number" }
           }
      }
于 2014-06-25T12:59:33.980 回答
0

我不确定这是否是您的问题的一部分,但在您的 DataSource 的模式模型中,您指定 ID 是名为“BonusId”的字段,但该字段未在字段数组中指定。

于 2013-05-04T18:56:35.667 回答
0

这可能无法解决提问者的问题,但希望可以帮助遇到同样问题的人。

对我们来说,这个问题是由 JSON 中返回的错误引起的。一些必需的属性没有值,但与我们在网格中显示的数据无关。在网格中给这些属性一个默认值解决了这个问题。

您可以使用Fiddler Web Debugging Tools查看返回的 JSON 。

于 2014-08-07T13:11:02.403 回答