Kendo Grid不会为我处理脏物品。为什么?

时间:2013-01-21 13:41:24

标签: asp.net-mvc kendo-ui

我的mvc项目中有一个kendo网格(内联模式),我用mvc初始化了网格。 问题是,当我添加一个新行时,它获得一个0 id,并且它的dirty属性设置为true。 如何刷新添加的项目并为其设置正确的ID?

这是我的剑道网格:

@(Html.Kendo().Grid<IranHost.Tools.Services.Core.DataModel.Site>()
                                    .Name("grid")
                                    .Columns(columns =>
                                    {
                                        columns.Bound(p => p.Domain).Width(250).Title("دامین");
                                        columns.Command(command => { command.Edit().Text("ویرایش").UpdateText("ذخیره").CancelText("لغو"); command.Destroy().Text("حذف"); });
                                    })
                                    .ToolBar(toolbar => toolbar.Create().Text("افزودن دامین جدید").HtmlAttributes(new { @class = "add-button" }))
                                    .Editable(editable => { editable.Mode(GridEditMode.InLine); })
                                    .Sortable()
                                    .Pageable()
                                    .Scrollable()
                                    .Events(action => { action.Edit("gridEdit"); action.Save("gridSave"); action.SaveChanges("gridSaveChanges"); })
                                    .DataSource(dataSource => dataSource
                                        .Ajax()
                                        .Events(events => { events.Error("result_handler"); })
                                        .Model(model => model.Id(p => p.Id))
                                        .Create(create => create.Action("AddDomain", "Service", new { customerID = ViewBag.CustomerId }))
                                        .Read(read => read.Action("GetDomainListForGrid", "Service", new { customerID = ViewBag.CustomerId }))
                                        .Update(update => update.Action("EditDomain", "Service"))
                                        .Destroy(destroy => destroy.Action("DeleteDomain", "Service"))
                                    )
                                    )

这就是我在服务器端所做的:

public ActionResult AddDomain([DataSourceRequest] DataSourceRequest request, DataModel.Site site)
    {
        if (ModelState.IsValid)
        {
            var pattern = "([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w\\.-]*)";
            if (!Regex.IsMatch(site.Domain, pattern))
            {
                //TODO: Must be added in the framework.
                ModelState.AddModelError("ERROR", "Wrong URL Format!");
                return Json(ModelState.ToDataSourceResult(), JsonRequestBehavior.AllowGet);
            }

            var siteContext = new Biz.Site(DataContext);
            siteContext.Add(site);
            DataContext.SaveChanges();
            ModelState.AddModelError("ADDED", site.id);
            return Json(new[] { site }.ToDataSourceResult(request, ModelState), JsonRequestBehavior.AllowGet);
        }

        return new HttpStatusCodeResult(403);
    }

但它仍然不起作用!

3 个答案:

答案 0 :(得分:0)

创建新记录时,默认的int id值为0。

这个想法是当您点击保存按钮时,记录被发送到服务器,您需要返回具有更新ID(从数据库中检索到的ID)的项目。然后当网格读取该值并且看到它与默认值(零)不同时,它将返回客户端,它将新记录标记为已成功插入。 如果没有返回任何项目或缺少更新的id值,Grid将继续将记录标记为脏,并且在将来的save / saveChanges按钮点击时它将继续将其重新发送到服务器。

如果要更改默认ID值,可以在模型定义中使用DefaultValue方法。

.Model(model => model.Id(p => p.Id).DefaultValue(-42))

答案 1 :(得分:0)

您需要在任何CRUD操作后将记录返回到网格。您甚至希望在Destory上执行此操作以返回error_handler事件的错误。这是我在这里发布的一些答案上使用的代码,还有一些额外的东西,但你应该看的是单个记录如何像初始Read一样转换为List。如果需要,请查看我的其他答案以获取有关模型和FlattenToThis的更多详细信息。但我认为这应该足以让你到达目的地。

[HttpPost]
public JsonResult CreatePerson([DataSourceRequest]DataSourceRequest request, Person person)
{
    if (ModelState.IsValid)
    {
        try
        {
            person = _personDataProvider.Create(person);
        }
        catch (Exception e)
        {
            ModelState.AddModelError(string.Empty, e.InnerException.Message);
        }
    }
    var persons = new List<Person> {person};
    DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request, ModelState);
    return Json(result, JsonRequestBehavior.AllowGet);
}

public JsonResult ReadPeople([DataSourceRequest]DataSourceRequest request)
{
    var persons = _personDataProvider.Read(false);
    DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request);
    return Json(result, JsonRequestBehavior.AllowGet);
}

[HttpPost]
public JsonResult UpdatePerson([DataSourceRequest]DataSourceRequest request, Person person)
{
    if (ModelState.IsValid)
    {
        try
        {
            person = _personDataProvider.Update(person);
        }
        catch (Exception e)
        {
            ModelState.AddModelError(string.Empty, e.InnerException.Message);
        }
    }
    var persons = new List<Person>() {person};
    DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request, ModelState);
    return Json(result, JsonRequestBehavior.AllowGet);
}

[HttpPost]
public JsonResult DestroyPerson([DataSourceRequest]DataSourceRequest request, Person person)
{
    if (ModelState.IsValid)
    {
        try
        {
            person = _personDataProvider.Destroy(person);
        }
        catch (Exception e)
        {
            ModelState.AddModelError(string.Empty, "There was an error deleting this record, it may still be in use.");
        }
    }
    var persons = new List<Person>() {person};
    DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request, ModelState);
    return Json(result, JsonRequestBehavior.AllowGet);
}

答案 2 :(得分:0)

问题解决了! 我使用的是旧版本的KendoUI,它没有requestEnd所以我开始使用AddModelError来处理服务器端的结果。 实际上我使用AddModelError不是为了错误,而是告诉客户端添加/编辑项目是成功的。

实际上这是一个非常糟糕的主意但我暂时没有选择。在客户端,我提出了Events.Error(“result_handler”)。剑道虽然它确实是一个错误,所以它没有对ui做任何改变,但将dirty属性设置为true!

现在我的老板正在试图获得新版本的KendoUI,我正在使用ajaxComplete来引发其他事件。不幸的是,在我拿到新版本之前,我真的没有多少选择!