剑道UI网格插入/更新创建重复记录(再次)



我和Daniel在这个话题上有同样的问题,但是他的解决方案对我不起作用:

http://www.kendoui.com/forums/ui/grid/kendo-ui-grid-inserts-updates-create-duplicate-records.aspx -jhxqRrNAUGsTFJaC-Ojwg

用例。Users依次添加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

    "Bob | 20 |秒" ID = 2

    "Alex | 10 | first" 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
    }

UI代码
// 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 
            });

我还没有在我的代码中看到这个问题。然而,我确实有一个"完整"的事件处理程序在我的创建和更新事件刷新网格-它可能会帮助你:

  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();
            }
        }
    },
   ...

是的,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));
    }

当读取操作中未将主键传递给视图时,会发生此错误。

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

我使用的是kendo的c# MVC的html助手,它不暴露同步事件,所以我必须在设置网格后修改它。

On window load:

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

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

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

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。

   '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

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

我也遇到过类似的问题。

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

model: {
      id: "Id",
      fields: {
           Id: { editable: false, type: "number" },
           AnotherName: { editable: true, type: "string" },
           AnotherId: { editable: true, type: "number" }
           }
      }

这可能不能解决提问者的问题,但希望对遇到同样问题的人有所帮助。

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

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

相关内容

最新更新