如何只更新Telerik MVC网格中的行而不刷新网格数据?

时间:2014-03-14 17:00:15

标签: asp.net-mvc telerik

从示例和文档中看,如果我想在Telerik网格中更新一行(或进行批量更新),我还需要刷新整个网格中的数据。

有没有办法只更新客户端上的那一行,而不是每次想要更新时都不返回所有网格数据?每次保持返回那么多数据似乎非常浪费。 即使我进行批量更新,为什么还需要返回所有新数据?

1 个答案:

答案 0 :(得分:0)

通常,数据库有很多用户,您的用户界面可能被多人访问。如果网格将要更新,那么它将包括自最初加载网格以来可能发生在数据上的任何其他更改。

网格允许您通过分页选项限制一次显示的记录数。在我们的项目中,我们使用AJAX加载网格,并在控制器中使用IQueryable。当我们在IQueryable上调用ToDataSourceResult(request)时,它只检索所需的数据,并且不从数据库加载完整的表。

在Razor View上:

@(Html.Kendo().Grid<WebApp.ViewModels.AccountViewModel>()
    .Name("Accounts")
    .Columns(columns =>
    {
        columns.Bound(c => c.AccountNumber);
        columns.Bound(c => c.Name);
        columns.Bound(c => c.Address1);
        columns.Bound(c => c.Address2);
        columns.Bound(c => c.City);
        columns.Bound(c => c.State);
        columns.Bound(c => c.Zip);
        columns.Bound(c => c.PrimaryContact).Title("Contact");
    })
    .Filterable(filterable => filterable
        .Extra(false)
        .Operators(operators => operators
            .ForString(str => str.Clear()
                .Contains("Contains")
                .DoesNotContain("Doesn't Contain")
            )
        )
    )
    .Groupable()
    .Sortable()
    .Pageable(pageable => pageable
        .Refresh(true)
        .PageSizes(new int[] { 5, 10, 20, 50, 100, 500 })
        .ButtonCount(5)
    )
    .DataSource(dataSource => dataSource
        .Ajax()
        .Sort(sort => sort.Add("Name").Ascending())
        .PageSize(20)
        .Read(read => read.Action("Account_Read", "Account"))
    )
)

然后在控制器中:

public ActionResult Account_Read([DataSourceRequest] DataSourceRequest request)
{
    var jsonlist = GetAccounts()
        .Select(sa => new AccountViewModel
        {
            ID = sa.ID,
            AccountNumber = sa.AccountNumber,
            Name = sa.Name,
            Address1 = sa.Address1,
            Address2 = sa.Address2,
            City = sa.City,
            State = sa.State,
            Zip = sa.Zip,
            PrimaryContact = sa.User.FirstName + " " + sa.User.LastName
        }
    ).ToDataSourceResult(request);

    return Json(jsonlist);
}

<强>更新

我们在其中一个Kendo网格上有一个内联编辑表单。我们花了一点时间才弄明白。在Razor视图中:

@(Html.Kendo().Grid<DataViewModel>()
    .Name("Data")
    .Columns(columns =>
    {
        columns.Bound(c => c.FieldName)
            .EditorTemplateName("DataFieldName")
            .Title("Item Name")
            .Width(200);
        columns.Bound(c => c.TextValue)
            .Title("Text");
        columns.Command(command => { command.Edit(); command.Destroy(); })
            .Title("Actions")
            .Width(172);
    })
    .Filterable()
    .Sortable()
    .Pageable(pageable => pageable
        .Refresh(true)
        .PageSizes(new int[] { 5, 10, 20, 50, 100 })
        .ButtonCount(5)
    )
    .ToolBar(toolbar => toolbar.Create())
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Sort(sort => sort.Add("CreatedDate").Descending())
        .PageSize(20)
        .Events(events => events.Error("error_handler"))
                .Model(model =>
                {
                    model.Id(pd => pd.ID);
                    model.Field(pd => pd.CreatedDate).Editable(false);
                    model.Field(pd => pd.ValuesID).DefaultValue(Model.Values.ID);
                })
        .Read(read => read.Action("Data_Read", "History", new { ValuesID = Model.Values.ID }))
        .Create(update => update.Action("Data_Create", "History"))
        .Update(update => update.Action("Data_Update", "History"))
        .Destroy(update => update.Action("Data_Destroy", "History"))
    )
)

<script type="text/javascript">
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }
</script>

为了使用日期选项的剑道日期时间选择器,我们必须创建一个自定义编辑器模板。我们在Views >> Shared >> EditorTemplates下创建了一个新文件夹。文件名是DataFieldName.cshtml:

@model WebApp.ViewModels.DataViewModel
@using WebApp.ViewModels

@(Html.Kendo().ComboBox()
    .Name("FieldName")
    .Placeholder("Select/Create Item Name")
    .DataTextField("Name")
    .DataValueField("Name")
    .Filter(FilterType.Contains)
    .DataSource(source => source
        .Read(read => read.Action("GetFieldNames", "History"))
    )
)

然后控制器具有AJAX调用的所有操作结果:

[HttpPost]
public ActionResult Data_Create(DataViewModel DataIn)
{
    var Data = new Data();
    Data.ValuesID = DataIn.ValuesID;
    Data.FieldName = DataIn.FieldName;
    Data.TextValue = DataIn.TextValue;
    if (DataIn.TimeValue != null) Data.TimeValue = DataIn.TimeValue;

    if (ModelState.IsValid)
    {
        db.Datas.Add(Data);
        db.SaveChanges();
    }

    return RedirectToAction("EditValue", new
    {
        ValueID = DataIn.ValuesID,
        tankID = db.Values.FirstOrDefault(pv => pv.ID == DataIn.ValuesID).TankID
    });
}

[HttpPost]
public ActionResult Data_Update(DataViewModel DataIn)
{
    var Data = db.Datas.Find(DataIn.ID);
    Data.FieldName = DataIn.FieldName;
    Data.TextValue = DataIn.TextValue;
    if (DataIn.TimeValue != null) Data.TimeValue = DataIn.TimeValue;

    if (ModelState.IsValid)
    {
        db.Entry(Data).State = EntityState.Modified;
        db.SaveChanges();
    }

    return RedirectToAction("EditValue", new
    {
        ValueID = DataIn.ValuesID,
        tkID = db.Values.FirstOrDefault(pv => pv.ID == DataIn.ValuesID).tkID
    });
}

[HttpPost]
public ActionResult Data_Destroy(DataViewModel DataIn)
{
    var Data = db.Datas.Find(DataIn.ID);

    db.Datas.Remove(Data);
    db.SaveChanges();

    return RedirectToAction("EditValue", new
    {
        ValueID = DataIn.ValuesID,
        tkID = db.Values.FirstOrDefault(pv => pv.ID == DataIn.ValuesID).tkID
    });
}

public ActionResult GetFieldNames()
{
    var jsonList = db.Datas
        .Select(pd => new 
        {
            Name = pd.FieldName 
        })
        .Distinct()
        .OrderBy(pd => pd.Name)
        .ToList();

    return Json(jsonList, JsonRequestBehavior.AllowGet);
}