【问题标题】:Kendo UI Grid posting back already Inserted Rows againKendo UI Grid 再次回发 Inserted Rows
【发布时间】:2025-12-16 17:25:01
【问题描述】:

我遇到了问题,当插入成功完成并且我继续插入另一行时,在下一个插入中它也会发送之前成功插入的行,所以它是这样的。 在第一次插入时,该行被发送回 webAPI 并成功插入。 On Next Insert 发送两行,其中一个来自第一步。 在第三个插入它发送前两行以及第三行等等。

这可能是什么原因?

这是有问题的代码。

$(document).ready(function () {
try {

var degreeYearsArray = new Array();

function GetDegreeName(dgID, degreeName) {
    for (var i = 0; i < degreeYearsArray.length; i++) {
        if (degreeYearsArray[i].dgID_PK == dgID) {
            return degreeYearsArray[i].Name;
        }
    }
    return degreeName;
}

var degreeYearModel = {
    id: "DGYR_PK",
    fields: {
        DGID_FK: {
            type: "number",
            nullable: false,
            editable: false
        },
        Code: {
            type: "string",
            validation: {
                required: true,
                minlength: 2,
                maxlength: 160
            }
        },
        Year: {
            type: "number",
            validation: {
                required: true
            }
        },
        EffectiveDate: {
            type: "date",
            validation: true

        },
        TerminationDate: {
            type: "date",
            validation: true
        }
    }
}; 




var baseURL = "http://localhost:3103/api/Degree";
var degreeYearTransport = {
    create: {
        url: baseURL + "/PostDegreeYears", // "/PutOrgSchool",
        type: "POST",
        // contentType: "application/json"
        dataType: "json"
    },
    read: {
        url: function () {
            var newURL = "";
            if (window.SelectedDegree == null)
                newURL =   baseURL + "/GetDegreeYears"
            else
                newURL =  baseURL + "/GetDegreeYears?degreeID=" + window.SelectedDegree.DGID_PK;
            return newURL;
        },
       dataType: "json" // <-- The default was "jsonp"
    },
    update: {
        url: baseURL + "/PutDegreeYears", //"/PostOrgSchool",
        type: "PUT",
        // contentType: "application/json",
        dataType: "json"
    },
    destroy: {
        url: function (employee) {
            return baseURL + "/deleteOrg" + employee.Id
        },
        type: "DELETE",
        dataType: "json",
        contentType: "application/json"
    },
    parameterMap: function (options, operation) {
        try {


            if (operation != "read") {
                options.EffectiveDate = moment(options.EffectiveDate).format("MM-DD-YYYY");
                options.TerminationDate = moment(options.TerminationDate).format("MM-DD-YYYY")
            }
            var paramMap = kendo.data.transports.odata.parameterMap(options);

            delete paramMap.$format; // <-- remove format parameter.

            return paramMap;

        } catch (e) {
            console.error("Error occure in parameter Map or Degree.js" + e.message);
        }

    }
}; //transport




var dsDegreeYears = new kendo.data.DataSource({
    serverFiltering: true, // <-- Do filtering server-side
    serverPaging: true, // <-- Do paging server-side
    pageSize: 2,
    transport: degreeYearTransport,
    requestEnd: function (e) {
        try {
            if (e.type == "update"){
                $.pnotify({
                    title: 'Update Sucessful',
                    text: 'Record was Updated Successfully',
                    type: 'success'
                });
            }

            if (e.type == "create") {
                $.pnotify({
                    title: 'Insert Sucessful',
                    text: 'Record was Inserted Successfully',
                    type: 'success'
                });
            }
        } catch (e) {
            console.error("error occured in requestEnd of dsDegreeYears datasource in DegreeYears.js" + e.message);
        }

    },
    schema: {
        data: function (data) {
            return data.Items; // <-- The result is just the data, it doesn't need to be unpacked.
        },
        total: function (data) {
            return data.Count; // <-- The total items count is the data length, there is no .Count to unpack.
        },
        model: degreeYearModel
    }, //schema
    error: function (e) {
        var dialog = $('<div></div>').css({ height: "350px", overflow: "auto" }).html(e.xhr.responseText).kendoWindow({
            height: "300px",
            modal: true,
            title: "Error",
            visible: false,
            width: "600px"

        });

        dialog.data("kendoWindow").center().open();
    },

});


$("#" + gridName).kendoGrid({
    dataSource: dsDegreeYears,
    autoBind: false,
    groupable: true,
    sortable: true,
    selectable: true,
    filterable: true,
    reorderable: true,
    resizable: true,
    columnMenu: true,
    height: 430,
    editable: "inline",
    toolbar: ["create"],
    pageable: {
        refresh: true,
        pageSizes: true,
        buttonCount: 5
    },
    columns: [  {
                    field: "DGID_FK",
                    title: "Degree Name",
                    width: 140,
                    template: function (dataItem) {
                        if (window.SelectedDegree != null) {
                            dataItem.DGID_FK = window.SelectedDegree.DGID_PK;
                            return window.SelectedDegree.Name;
                        }
                        else
                            return "";
                    }
                },
                {
                    field: "Code",
                    title: "Code",
                    width: 140
                },
                 {
                     field: "Year",
                     title: "Year",
                     width: 140
                 },
               {
                   field: "Description",
                   width: 110
               },

            {
                field: "EffectiveDate",
                width: 110,
                format: "{0:MM/dd/yyyy}"
            },
            {
                field: "TerminationDate",
                width: 110,
                format: "{0:MM/dd/yyyy}"
            },

             {
                 command: ["edit"] , title: "&nbsp;", width: "172px"
             }
    ]
}); //grid

//Hide history pull-down menu in the top corner
$.pnotify.defaults.history = false;
$.pnotify.defaults.styling = "bootstrap";
// styling: 'bootstrap'
//styling: 'jqueryui'


} catch (e) {
    console.error("Error occured in DegreeYears" + e.message);
}

}); // 文档

这是从 WebAPI 发送的响应

 {"$id":"1","DGYR_PK":27,"DGID_FK":64,"Year":4,"Code":"4THYR","EffectiveDate":"2014-01-11T00:00:00","TerminationDate":"2014-01-11T00:00:00","CreatedByUserID_FK":1,"DateCreated":"0001-01-01T00:00:00","UpdatedByUserID_FK":1,"DateUpdated":"0001-01-01T00:00:00","RowStatusID_FK":1,"Degree":null,"DegreeYearExamSchedules":[],"User":null,"RowStatu":null,"User1":null,"DegreeYearSubjects":[]}

所以我确实看到我正在返回用户在回答问题时建议的 ID。 还在疑惑

【问题讨论】:

    标签: kendo-ui kendo-grid


    【解决方案1】:

    如果您不返回新插入模型的“DGYR_PK”值,就会发生这种情况。数据源需要一个模型实例来设置其“id”字段,以免将其视为“新”。当您返回“ID”作为“创建”操作的响应时,数据源将正常工作。

    您可以查看此示例以了解完整的 Web API CRUD:https://github.com/telerik/kendo-examples-asp-net/tree/master/grid-webapi-crud

    Here是相关代码:

    public HttpResponseMessage Post(Product product)
    {
        if (ModelState.IsValid)
        {
            db.Products.AddObject(product);
            db.SaveChanges();
    
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, product);
            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = product.ProductID }));
            return response;
        }
        else
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您的主键不能为 0 或 null。如果您使用的是自动递增值,那么您应该在发布后调用数据源的“重新读取”​​。检查值并确保您的数据值 > 0。注意:我已将模型中 PK 的默认值设置为列模型中的 -1 以帮助解决此问题。

      【讨论】:

      • 是的,重新阅读帮助我解决了这个问题。想知道这是否是正确的解决方法,因为在成功插入时,我将返回对象以及新 ID。唯一的问题是效率(虽然不是在我的情况下,这对我来说很好),假设 getmethod 需要 10-15 秒(这种时间是有争议的),而不是这个解决方案变得不那么有效。感谢其他成员的回复,这帮助我更好地了解了可能的故障位置
      【解决方案3】:

      插入记录后,需要返回该行的id,否则grid也将前一行视为新行。

      在您的创建函数中,您调用网络 API

      baseURL + "/PostDegreeYears", // "/PutOrgSchool",

      在服务器端考虑下面的代码。

      public void Create(ABSModel model)
              {
                  try
                  {
                      using (context = new Pinc_DBEntities())
                      {
      
                              tblAB tb = new tblAB();
                              tb.ABS = model.ABS;
                              tb.AreaFacility = model.AreaFacility;
                              context.tblABS.Add(tb);
      
                              Save();
                              model.ABSID = tb.ABSID;//this is the important line of code, you are returning the just inserted record's id (primary key) back to the kendo grid after successfully saving the record to the database.
      
      
                      }
                  }
                  catch (Exception ex)
                  {
      
                      throw ex;
                  }
              }
      

      请根据您的要求调整上述示例。

      【讨论】:

        【解决方案4】:

        您可以附加并响应 DataSource 上的 requestEnd 事件。

        requestEnd: function(e) {
                if (e.type === "create") {
                    this.read();
                }
            }
        

        这就是说:“创建记录后,将条目(包括新创建的)重新读取到网格中”。从而为您提供新创建的带有 key 和 all 的条目。当然,您会看到额外的读取可能存在一些性能问题。

        【讨论】:

        • 更简单,更优雅。