使用 AJAX 绑定时创建/更新后具有 IEnumerable 属性的 Kendo Grid 模型未正确更新

Posted

技术标签:

【中文标题】使用 AJAX 绑定时创建/更新后具有 IEnumerable 属性的 Kendo Grid 模型未正确更新【英文标题】:Kendo Grid model with an IEnumerable property not updating correctly after Create/Update when using AJAX binding 【发布时间】:2013-07-03 23:06:34 【问题描述】:

我遇到了一个问题,即在将模型的属性发送到我的控制器以从 Kendo Grid 进行更新或创建调用时没有正确更新。模型如下所示:

public class ReleaseNotesModel

    public int NoteID  get; set; 
    public int ReleaseID  get; set; 
    public List<TranslationModel> ReleaseNoteTranslations  get; set; 
    public ReleaseNoteType ItemType  get; set; 

public class TranslationModel

    public int TranslationID  get; set; 
    public string Translation  get; set; 
    public int LanguageID  get; set; 
    public int ItemID  get; set; 

这是我认为的网格:

@(html.Kendo().Grid<ReleaseNotesModel>()
    .Name("Grid")
    .Columns(columns =>
    
        columns.Bound(m => m.ItemType).Width(140);
        columns.Bound(m => m.Description);
        columns.Command(command =>
            
                command.Edit();
                command.Destroy();
            ).Width(170);
    )
    .ToolBar(toolbar => toolbar.Create())
    .Editable(editable => editable
        .Mode(GridEditMode.PopUp)
        .TemplateName("ReleaseNoteTemplate")
        .Window(w => w.Width(620))
        .DisplayDeleteConfirmation(true)
    )
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .ServerOperation(false)
        //.Server()
        .Events(e => e.Error("grid_error"))
        .Model(model =>
        
            model.Id(m => m.NoteID);
            model.Field(m => m.ReleaseID).DefaultValue(Model.ReleaseID);
            model.Field(m => m.ItemType).DefaultValue(ReleaseNoteType.NewFeature);
            //defaultTranslationsList is a List<TranslationModel> with two empty objects in it
            model.Field(m => m.ReleaseNoteTranslations).DefaultValue(defaultTranslationsList);
        )
        .PageSize(5)
        .Read(read => read.Action("GetNotes", "ReleaseNotes", new  releaseID = Model.ReleaseID ))
        .Create(create => create.Action("AddNote", "ReleaseNotes"))
        .Update(update => update.Action("EditNote", "ReleaseNotes"))
        .Destroy(destroy => destroy.Action("DeleteNote", "ReleaseNotes"))
    )
)

更具体地说,我遇到的问题是在我的控制器操作中:

public async Task<ActionResult> EditNote(ReleaseNotesModel model)

model.ReleaseNoteTranslations 始终包含两个空对象(属性为 null 或 0),即我为此属性设置的默认值。如果我没有设置默认值,那么我将不会在弹出编辑器中为该属性编辑任何字段。所有其他属性都按预期更新。

让我烦恼的是,如果我使用服务器绑定而不是 AJAX,那么所有数据都会被正确接收。所以我决定检查两种情况下发送的请求标头中的数据:

// Using server binding
ReleaseID:300
NoteID:886
ItemType:1
ReleaseNoteTranslations[0].ItemID:886
ReleaseNoteTranslations[0].LanguageID:1
ReleaseNoteTranslations[0].TranslationID:869
ReleaseNoteTranslations[0].Translation:The module is now released!
ReleaseNoteTranslations[1].ItemID:886
ReleaseNoteTranslations[1].LanguageID:2
ReleaseNoteTranslations[1].TranslationID:870
ReleaseNoteTranslations[1].Translation:Le module est maintenant disponible!
NoteID:886

// Using AJAX binding
sort:
group:
filter:
NoteID:886
ReleaseID:300
ReleaseNoteTranslations[0][TranslationID]:869
ReleaseNoteTranslations[0][Translation]:The module is now released!
ReleaseNoteTranslations[0][LanguageID]:1
ReleaseNoteTranslations[0][ItemID]:886
ReleaseNoteTranslations[1][TranslationID]:870
ReleaseNoteTranslations[1][Translation]:Le module est maintenant disponible!
ReleaseNoteTranslations[1][LanguageID]:2
ReleaseNoteTranslations[1][ItemID]:886
ItemType:1

现在我首先注意到的是 objectName[index].PropertyNameobjectName[index][PropertyName] 的语法

我想知道这是否是我的问题的原因,如果是这样,我有没有办法直接操纵发送的数据来修复它?这可能是 Kendo Grid 通过 Ajax 绑定发送数据的方式中的一个错误吗?

无论哪种方式,任何帮助都将不胜感激!

【问题讨论】:

您已经能够在弹出编辑器中创建另一个网格?并一次保存所有TranslationModelReleaseNotesModel?我这样做有问题。 其实我只是在弹出编辑器中显示了一个 textarea 元素的列表,我从来没有尝试过用网格来做。 【参考方案1】:

因此,如果将来有人偶然发现此问题,我联系了 Telerik 支持,他们向我解释说:

dataSource 只支持值类型,不会序列化 模型绑定器所期望的格式的数组。

他们还为我提供了一种解决方法,使用 request Data 函数调用 javascript 函数,将数据转换为正确的格式。

在视图中,通过指定要调用的 JavaScript 函数的名称来修改请求函数:

.Create(create => create.Action("AddNote", "ReleaseNotes").Data("serialize"))

然后添加将进行转换的函数:

function serialize(data) 
    for (var property in data) 
        if ($.isArray(data[property])) 
            serializeArray(property, data[property], data);
        
    

function serializeArray(prefix, array, result) 
    for (var i = 0; i < array.length; i++) 
        for (var property in array[i]) 
            result[prefix + "[" + i + "]." + property] = array[i][property];
        
    

【讨论】:

非常感谢。我整天都在寻找答案。就是这样。 我的数据对象中多了一个内部对象..如何应用到我的网格?【参考方案2】:

另一个问题可能是 kendo.aspnet.mvc.js 未包含在项目中。它似乎在包含时执行序列化技巧。

【讨论】:

我实际上一直包含该脚本,只是添加手动序列化解决了我的问题。【参考方案3】:

我注意到你需要添加 if 条件,因为如果计数为 1,则不需要序列化,只有一项可以在没有序列化的情况下正常工作

【讨论】:

以上是关于使用 AJAX 绑定时创建/更新后具有 IEnumerable 属性的 Kendo Grid 模型未正确更新的主要内容,如果未能解决你的问题,请参考以下文章

Ajax 更新后在 jQuery 中重新绑定事件(更新面板)

Ajax 更新后在 jQuery 中重新绑定事件(更新面板)

我可以有一个持久的 PDO 对象,它只接受从 AJAX 调用绑定的新变量吗?

Telerik ASP.NET AJAX - 具有动态创建的 Docks 的 Ajax 更新标签

当更新一个表单(使用 Ajax)时,重新加载表单使它们具有与先前更新的相同的值

ajax查询后如何更新knppaginatorbundle的分页模板