Kendo UI MVC内联客户端网格 - 单击取消删除行。不是型号ID问题

时间:2021-12-05 01:18:05

I have a Kendo grid set up for client-side only. Whenever I add a row, then edit it, then cancel - it gets removed. Multiple questions have been asked here and on the Kendo forums about this same issue, and all the suggestions point to incorrect setup of the model's ID.

我只为客户端设置了一个Kendo网格。每当我添加一行,然后编辑它,然后取消 - 它将被删除。在这里和Kendo论坛上已经提出了关于同一问题的多个问题,并且所有建议都指向模型ID的错误设置。

Well, in my case the ID seems to be set up correctly. I am assigning a new ID to the model in the onGridSave() javascript event, like this:

好吧,就我而言,ID似乎设置正确。我在onGridSave()javascript事件中为模型分配了一个新ID,如下所示:

var _curId = 1;
function onGridSave(e) {
    var newId = _curId++;
    e.model.set('id', newId);
    e.model.set('EncryptedIngredientId', newId);
}

And when I look at the data in the grid after having added multiple rows, all of their IDs are unique - from 1 to n.

当我在添加多行后查看网格中的数据时,它们的所有ID都是唯一的 - 从1到n。

But when I cancel an edit, in the onGridChange() event the action is "remove", and the cancelled row is removed. This happens for new rows as well as for edited rows, while it should only be the case for new rows.

但是当我取消编辑时,在onGridChange()事件中,操作是“删除”,并且删除了取消的行。对于新行和已编辑的行都会发生这种情况,而新行只应该是这种情况。

The grid is set up as follows:

网格设置如下:

@(Html.Kendo().Grid<IngredientViewModel>(Model.ServerData)

    .Name("IngredientsGrid")
    .Editable(editable => editable.Mode(GridEditMode.InLine).Enabled(true))
    .BindTo(Model.DataAfterEdit ?? Model.ServerData)
    .DataSource(ds => ds
        .Ajax()
        .ServerOperation(false)
        .Events(ev => ev.Change("onGridChange").Error("onGridError"))
        .Model(m => {
                 m.Id(p => p.EncryptedIngredientId);
                 m.Field(p => p.EncryptedIngredientId).DefaultValue(Guid.NewGuid().ToString());
                 m.Field(p => p.PercentInfo).DefaultValue(new PercentInfoViewModel());
             })
        .Read("IngGrid_Read", "Company") // <-- dummy action that doesn't exist in controller
        .Update("IngGrid_Update", "Company") // <-- dummy action that doesn't exist in controller
        .Create("IngGrid_Create", "Company") // <-- dummy action that doesn't exist in controller
        .Destroy("IngGrid_Destroy", "Company")) // <-- dummy action that doesn't exist in controller
    .ToolBar(tbar => tbar.Create())
    .Columns(c => {
               c.AutoGenerate(false);
               c.Bound(m => m.CasNumber);
               c.Bound(m => m.IngredientName);
               c.Bound(m => m.PercentInfo).ClientTemplate("#= makePercentageDisplayString(data.PercentInfo) #").Width(180);
               c.Bound(m => m.ReachRegNumber);
               c.Bound(m => m.ReachSvhc);
               c.Bound(m => m.RohsSubstance);
               c.Bound(m => m.Prop65Substance);
               c.Command(command => {
                             command.Edit();
                             command.Destroy();
                         }).Width(200);
           })
    .Events(evt => {
                evt.Save("onGridSave");
                evt.Edit("onGridEdit");
            })
)

What am I doing wrong?

我究竟做错了什么?

2 个解决方案

#1


0  

When you declare this dummy actions, Kendo is trying to save data after you edit your cell. It perform create action but doesn't have correct response from the server so it believe that request was fail. Because of that it trying to remove row after you click cancel, cuz it can't find it in their dataSource.

If it gonna be just local grid as you said, the solution is add .Batch(true) on you grid dataSource config to prevent update action after you change cell.

If you wanna save your edited data on the server you should implement Update, Create and Destroy action correctly.

当您声明此虚拟操作时,Kendo会在您编辑单元格后尝试保存数据。它执行创建操作但没有来自服务器的正确响应,因此它认为请求失败。因为它在您单击取消后尝试删除行,因为它无法在其dataSource中找到它。如果它只是你所说的本地网格,解决方案是在你的网格dataSource配置上添加.Batch(true)以防止在更改单元格后更新操作。如果要将编辑后的数据保存在服务器上,则应正确实施“更新”,“创建”和“销毁”操作。

#2


0  

I also asked my question here: http://www.telerik.com/forums/mvc---inline-client-side-grid---clicking-cancel-removes-row-probably-not-the-model-id-issue-#qn5VWKCX9kmpZnLuTzDveQ

我也在这里问了我的问题:http://www.telerik.com/forums/mvc---inline-client-side-grid---clicking-cancel-removes-row-probably-not-the-model-id -issue-#qn5VWKCX9kmpZnLuTzDveQ

It turns out this is not supported when using MVC wrappers, however it could be done using JavaScript. Since I didn't want to lose the type safety of C#, I implemented the CRUD actions on the controller and store rows in the session.

事实证明,使用MVC包装器时不支持此功能,但可以使用JavaScript完成。由于我不想失去C#的类型安全性,我在控制器上实现了CRUD操作并在会话中存储行。

The only 2 things I had to change in my grid definition were: set .ServerOperation(true) instead of false; and remove the .BindTo(...) call. Resulting code looks like this:

我必须在网格定义中改变的唯一两件事是:set .ServerOperation(true)而不是false;并删除.BindTo(...)调用。结果代码如下所示:

@(Html.Kendo().Grid<IngredientViewModel>(Model.ServerData)

.Name("IngredientsGrid")
.Editable(editable => editable.Mode(GridEditMode.InLine).Enabled(true))
.DataSource(ds => ds
    .Ajax()
    .ServerOperation(true)
    .Events(ev => ev.Change("onGridChange").Error("onGridError"))
    .Model(m => {
             m.Id(p => p.EncryptedIngredientId);
             m.Field(p => p.EncryptedIngredientId).DefaultValue(Guid.NewGuid().ToString());
             m.Field(p => p.PercentInfo).DefaultValue(new PercentInfoViewModel());
         })
    .Read("IngGrid_Read", "Company") // <-- dummy action that doesn't exist in controller
    .Update("IngGrid_Update", "Company") // <-- dummy action that doesn't exist in controller
    .Create("IngGrid_Create", "Company") // <-- dummy action that doesn't exist in controller
    .Destroy("IngGrid_Destroy", "Company")) // <-- dummy action that doesn't exist in controller
.ToolBar(tbar => tbar.Create())
.Columns(c => {
           c.AutoGenerate(false);
           c.Bound(m => m.CasNumber);
           c.Bound(m => m.IngredientName);
           c.Bound(m => m.PercentInfo).ClientTemplate("#= makePercentageDisplayString(data.PercentInfo) #").Width(180);
           c.Bound(m => m.ReachRegNumber);
           c.Bound(m => m.ReachSvhc);
           c.Bound(m => m.RohsSubstance);
           c.Bound(m => m.Prop65Substance);
           c.Command(command => {
                         command.Edit();
                         command.Destroy();
                     }).Width(200);
       })
.Events(evt => {
            evt.Save("onGridSave");
            evt.Edit("onGridEdit");
        })

)

#1


0  

When you declare this dummy actions, Kendo is trying to save data after you edit your cell. It perform create action but doesn't have correct response from the server so it believe that request was fail. Because of that it trying to remove row after you click cancel, cuz it can't find it in their dataSource.

If it gonna be just local grid as you said, the solution is add .Batch(true) on you grid dataSource config to prevent update action after you change cell.

If you wanna save your edited data on the server you should implement Update, Create and Destroy action correctly.

当您声明此虚拟操作时,Kendo会在您编辑单元格后尝试保存数据。它执行创建操作但没有来自服务器的正确响应,因此它认为请求失败。因为它在您单击取消后尝试删除行,因为它无法在其dataSource中找到它。如果它只是你所说的本地网格,解决方案是在你的网格dataSource配置上添加.Batch(true)以防止在更改单元格后更新操作。如果要将编辑后的数据保存在服务器上,则应正确实施“更新”,“创建”和“销毁”操作。

#2


0  

I also asked my question here: http://www.telerik.com/forums/mvc---inline-client-side-grid---clicking-cancel-removes-row-probably-not-the-model-id-issue-#qn5VWKCX9kmpZnLuTzDveQ

我也在这里问了我的问题:http://www.telerik.com/forums/mvc---inline-client-side-grid---clicking-cancel-removes-row-probably-not-the-model-id -issue-#qn5VWKCX9kmpZnLuTzDveQ

It turns out this is not supported when using MVC wrappers, however it could be done using JavaScript. Since I didn't want to lose the type safety of C#, I implemented the CRUD actions on the controller and store rows in the session.

事实证明,使用MVC包装器时不支持此功能,但可以使用JavaScript完成。由于我不想失去C#的类型安全性,我在控制器上实现了CRUD操作并在会话中存储行。

The only 2 things I had to change in my grid definition were: set .ServerOperation(true) instead of false; and remove the .BindTo(...) call. Resulting code looks like this:

我必须在网格定义中改变的唯一两件事是:set .ServerOperation(true)而不是false;并删除.BindTo(...)调用。结果代码如下所示:

@(Html.Kendo().Grid<IngredientViewModel>(Model.ServerData)

.Name("IngredientsGrid")
.Editable(editable => editable.Mode(GridEditMode.InLine).Enabled(true))
.DataSource(ds => ds
    .Ajax()
    .ServerOperation(true)
    .Events(ev => ev.Change("onGridChange").Error("onGridError"))
    .Model(m => {
             m.Id(p => p.EncryptedIngredientId);
             m.Field(p => p.EncryptedIngredientId).DefaultValue(Guid.NewGuid().ToString());
             m.Field(p => p.PercentInfo).DefaultValue(new PercentInfoViewModel());
         })
    .Read("IngGrid_Read", "Company") // <-- dummy action that doesn't exist in controller
    .Update("IngGrid_Update", "Company") // <-- dummy action that doesn't exist in controller
    .Create("IngGrid_Create", "Company") // <-- dummy action that doesn't exist in controller
    .Destroy("IngGrid_Destroy", "Company")) // <-- dummy action that doesn't exist in controller
.ToolBar(tbar => tbar.Create())
.Columns(c => {
           c.AutoGenerate(false);
           c.Bound(m => m.CasNumber);
           c.Bound(m => m.IngredientName);
           c.Bound(m => m.PercentInfo).ClientTemplate("#= makePercentageDisplayString(data.PercentInfo) #").Width(180);
           c.Bound(m => m.ReachRegNumber);
           c.Bound(m => m.ReachSvhc);
           c.Bound(m => m.RohsSubstance);
           c.Bound(m => m.Prop65Substance);
           c.Command(command => {
                         command.Edit();
                         command.Destroy();
                     }).Width(200);
       })
.Events(evt => {
            evt.Save("onGridSave");
            evt.Edit("onGridEdit");
        })

)