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

Art*_*m G 3 json duplicates kendo-ui kendo-grid

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

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

    "Bob | 20 | second"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
    }
Run Code Online (Sandbox Code Playgroud)

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

奖金数据来源:

// 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 
            });
Run Code Online (Sandbox Code Playgroud)

Qui*_*rdt 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();
            }
        }
    },
   ...
Run Code Online (Sandbox Code Playgroud)


小智 6

是的,哈米德是对的。您的“创建”操作结果从您的模型中传入要保存到数据库中的对象。让数据访问层中的 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));
    }
Run Code Online (Sandbox Code Playgroud)