在 ASP.NET MVC 上使用 Kendo Grid 更改数据

Posted

技术标签:

【中文标题】在 ASP.NET MVC 上使用 Kendo Grid 更改数据【英文标题】:data changes using Kendo Grid on ASP.NET MVC 【发布时间】:2021-04-29 18:14:50 【问题描述】:

在我的控制器中,我有 1 个返回所有数据的主要方法和 2 个返回数据子集的其他方法:

public class ReportController : Controller


    public ActionResult Index(String reportID, String reportName) 
        return View();
    

    [HttpPost]
    public async Task<JsonResult> ReadReport([DataSourceRequest] DataSourceRequest request) 
        var result = new DataSourceResult();
        try 
            var report = await _portal.ReadReport(_reportID);
            result = report.ToDataSourceResult(request);
         catch (Exception err) 
            result.Errors = err.Message;
        
        return new JsonResult  Data = result, MaxJsonLength = Int32.MaxValue ;
    

    [HttpPost]
    public async Task<JsonResult> ReadReportElectric([DataSourceRequest] DataSourceRequest request) 
        var result = new DataSourceResult();
        try 
            var report = await _portal.ReadReport(_reportID);
            var specific = report.Where(m => m.MeterType == "Electric");
            var meters = new Domain.GapMeters();
            meters.AddRange(specific);
            result = meters.ToDataSourceResult(request);
         catch (Exception err) 
            result.Errors = err.Message;
        
        return new JsonResult  Data = result, MaxJsonLength = Int32.MaxValue ;
    

    [HttpPost]
    public async Task<JsonResult> ReadReportGas([DataSourceRequest] DataSourceRequest request) 
        var result = new DataSourceResult();
        try 
            var report = await _portal.ReadReport(_reportID);
            var specific = report.Where(m => m.MeterType == "Gas");
            var meters = new Domain.GapMeters();
            meters.AddRange(specific);
            result = meters.ToDataSourceResult(request);
         catch (Exception err) 
            result.Errors = err.Message;
        
        return new JsonResult  Data = result, MaxJsonLength = Int32.MaxValue ;
    

在视图中,我有一个 Kendo TabStrip。第一个条显示所有记录,而其他 2 个选项卡显示“Electric”和“Gas”:

            @(html.Kendo().Window().Name("help-window").Visible(false).Title("Report Help").Resizable().Draggable().Height(540).Width(960).Content(@<text>
                <h3 class="panel-title">@GapReportResource.GapReport</h3>
                @(Html.Partial("~/Views/Shared/_Help.cshtml", new ViewDataDictionary   "reportName", ViewBag.ReportName  ))
            </text>))
            <div id="divPieChart" class="panel-heading">
                <h3 id="h3PieChart" class="panel-title" style="display: inline;">@ReportResource.ReportPieChart</h3>
                <a id="ahrefPieChart" title="Show report help" class="far fa-question-circle" style="display: inline; margin-left: 10px;"></a>
                <figure id="report-chart" class="ReportChart"></figure>
            </div>
            @(Html.Kendo().TabStrip()
                .Name("tabstrip")
                .Animation(animation => animation.Open(effect => effect.Fade(FadeDirection.In)))
                .Events(e => e
                    .Show("onTabShow")
                    .Select("onTabSelect")
                    .Activate("onTabActivate")
                    .Error("onTabError")
                )
                .Items(tabstrip =>
                
                    tabstrip
                        .Add()
                        .Selected(true)
                        .Content(@<text>
                            <div class="panel-heading">
                                <h3 class="panel-title">@ReportResource.Report</h3>
                            </div>
                            <div class="panel-body">
                                @(Html.Kendo().Grid<DataAnalysis.Domain.Meter>()
                                .Name("grid")
                                .Columns(c => 
                                    c.Bound(o => o.Parent).Title("Parent");
                                    c.Bound(o => o.Account).Title("Account");
                                    c.Bound(o => o.CustomerName).Title("Customer Name");
                                    c.Bound(o => o.Address).Title("Address");
                                    c.Bound(o => o.MeterNumber).Title("Meter Number");
                                    c.Bound(o => o.MeterType).Title("Meter Type");
                                    c.Bound(o => o.StartDate).Title("Start Date");
                                    c.Bound(o => o.EndDate).Title("End Date");
                                    c.Bound(o => o.Count).Title("Count");
                                )
                                .Sortable(o => o.SortMode(GridSortMode.SingleColumn))
                                .Pageable(p => p.Numeric(false).PreviousNext(false))
                                .Messages(m => m.NoRecords(""))
                                .Resizable(resizable => resizable.Columns(true))
                                .Scrollable(s => s.Endless(true))
                                .ToolBar(x => x.Custom().Text("Export").HtmlAttributes(new  href = "#", id = "export" ))
                                .DataSource(dataSource => dataSource
                                    .Ajax()
                                    .Read(read => read.Action("ReadReport", "Report"))
                                    .PageSize(20)
                                    .Events(e1 => 
                                        e1.RequestStart("onDataBound");
                                        e1.Error("onError");
                                    )
                                    .ServerOperation(false) // Paging, sorting, filtering and grouping is done client side
                                )
                                .AutoBind(false)
                                .Events(e => e.DataBound("onDataBound"))
                            </div>
                            </text>)
                        .Text("All");
                    tabstrip
                        .Add()
                        .Content(@<text>
                            <div class="panel-heading">
                                <h3 class="panel-title">@ReportResource.ReportElectric</h3>
                            </div>
                            <div class="panel-body">
                                @(Html.Kendo().Grid<DataAnalysis.Domain.Meter>()
                                .Name("gridElectric")
                                .Columns(c => 
                                    c.Bound(o => o.Parent).Title("Parent");
                                    c.Bound(o => o.Account).Title("Account");
                                    c.Bound(o => o.CustomerName).Title("Customer Name");
                                    c.Bound(o => o.Address).Title("Address");
                                    c.Bound(o => o.MeterNumber).Title("Meter Number");
                                    c.Bound(o => o.MeterType).Title("Meter Type");
                                    c.Bound(o => o.StartDate).Title("Start Date");
                                    c.Bound(o => o.EndDate).Title("End Date");
                                    c.Bound(o => o.Count).Title("Count");
                                )
                                .Sortable(o => o.SortMode(GridSortMode.SingleColumn))
                                .Pageable(p => p.Numeric(false).PreviousNext(false))
                                .Resizable(resizable => resizable.Columns(true))
                                .Scrollable(s => s.Endless(true))
                                .ToolBar(x => x.Custom().Text("Export").HtmlAttributes(new  href = "#", id = "export" ))
                                .DataSource(dataSource => dataSource
                                    .Ajax()
                                    .Read(read => read.Action("ReadReportElectric", "Report"))
                                    .PageSize(20)
                                    .Events(e1 => 
                                        e1.RequestStart("onDataBound");
                                        e1.Error("onError");
                                    )
                                    .ServerOperation(false) // Paging, sorting, filtering and grouping is done client side
                                )
                                .AutoBind(false)
                                .Events(e => e.DataBound("onDataBound"))
                            </div>
                            </text>)
                        .Text("Electric");
                    tabstrip
                        .Add()
                        .Content(@<text>
                            <div class="panel-heading">
                                <h3 class="panel-title">@ReportResource.ReportGas</h3>
                            </div>
                            <div class="panel-body">
                                @(Html.Kendo().Grid<DataAnalysis.Domain.Meter>()
                                .Name("gridGas")
                                .Columns(c => 
                                    c.Bound(o => o.Parent).Title("Parent");
                                    c.Bound(o => o.Account).Title("Account");
                                    c.Bound(o => o.CustomerName).Title("Customer Name");
                                    c.Bound(o => o.Address).Title("Address");
                                    c.Bound(o => o.MeterNumber).Title("Meter Number");
                                    c.Bound(o => o.MeterType).Title("Meter Type");
                                    c.Bound(o => o.StartDate).Title("Start Date");
                                    c.Bound(o => o.EndDate).Title("End Date");
                                    c.Bound(o => o.Count).Title("Count");
                                )
                                .Sortable(o => o.SortMode(GridSortMode.SingleColumn))
                                .Pageable(p => p.Numeric(false).PreviousNext(false))
                                .Resizable(resizable => resizable.Columns(true))
                                .Scrollable(s => s.Endless(true))
                                .ToolBar(x => x.Custom().Text("Export").HtmlAttributes(new  href = "#", id = "export" ))
                                .DataSource(dataSource => dataSource
                                    .Ajax()
                                    .Read(read => read.Action("ReadReportGas", "Report"))
                                    .PageSize(20)
                                    .Events(e1 => 
                                        e1.RequestStart("onDataBound");
                                        e1.Error("onError");
                                    )
                                    .ServerOperation(false) // Paging, sorting, filtering and grouping is done client side
                                )
                                .AutoBind(false)
                                .Events(e => e.DataBound("onDataBound"))
                            </div>
                            </text>)
                        .Text("Gas");
                )
            )

在 jQuery 中,我有这 2 个适合我的函数,但我无法弄清楚它们。第一个 onTabShow 在选择不同选项卡时触发。它正在调用数据库,但它在edata 中返回的数据是整个网页!

还有一个onDataBound 函数似乎只在第一次在主选项卡上加载数据时触发。出于某种原因,无论何时选择其他任何一个选项卡,它都不会触发。


function onTabShow(e) 
    var tab = $('#tabstrip > ul > li.k-item.k-state-default.k-tab-on-top.k-state-active > span.k-link');
    if (tab !== null) 
        var tabText = tab.text();
        var hashId = '#grid';
        if (tabText == 'All') 
            hashId = '#grid';
         else if (tabText == 'Electric') 
            hashId = '#gridElectric';
         else if (tabText == 'Gas') 
            hashId = '#gridGas';
        
        var grid = $(hashId).data('kendoGrid');
        console.log('onTabShow $(hashId) = ');
        console.log(grid);
        if (grid !== undefined) 
            $.ajax(
                url: GapReportsNS.GapReport,
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                success: function (edata) 
                    console.log('onTabShow(' + hashId + '): edata = ');
                    console.log(edata);
                    grid.setDataSource(new kendo.data.DataSource(
                        data: edata
                    ));
                
            );
        
    
;

function onDataBound(e) 
    var emptySpan = $('.empty-span');
    emptySpan.text('');
    $("#UP").toggle(false);
    var tab = $('#tabstrip > ul > li.k-item.k-state-default.k-tab-on-top.k-state-active > span.k-link');
    if (tab !== null) 
        var tabText = tab.text();
        var hashId = undefined;
        if (tabText == 'All') 
            hashId = undefined; // not necessary for 'All' (maybe, unless coming back from one of the specifics)
         else if (tabText == 'Electric') 
            hashId = '#gridElectric';
         else if (tabText == 'Gas') 
            hashId = '#gridGas';
        
        if (hashId !== undefined) 
            console.log('onDataBound (hashId): ' + hashId);
            var grid = $(hashId).data('kendoGrid');
            if (grid !== undefined) 
                //grid.dataSource.read();
                //if (this.dataSource.data.length > 1) 
                //    for (var i = 0; i < this.columns.length; i++) 
                //        this.autoFitColumn(i);
                //    
                //
            
        
    
;

有人可以帮忙吗?这些对我来说都是新技术。

【问题讨论】:

【参考方案1】:

关于活动的问题。下面是解释这两个事件作用的链接。

对于 tabStrip 事件:https://docs.telerik.com/kendo-ui/api/javascript/ui/tabstrip/events/show 对于网格事件:https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/events/databound

在您的代码中,您无需在 dataBound 事件中执行任何操作。

剩下的:

您应该首先按照文档中描述的方式编写控制器操作:https://demos.telerik.com/aspnet-mvc/grid/remote-data-binding

public ActionResult ReadReportElectric([DataSourceRequest]DataSourceRequest request)

    try 
        var report = await _portal.ReadReport(_reportID);
        var specific = report.Where(m => m.MeterType == "Electric");
        var meters = new Domain.GapMeters();
        meters.AddRange(specific);

        return Json(meters.ToDataSourceResult(request));
     catch (Exception err) 
        // You can return an empty list of your items here
        var meters = new List<>();

        // You can specify the error you want to be returned in your error event handler

        ModelState.AddModelError(string.Empty, "Error : " + err.ToString());

        return Json(meters.ToDataSourceResult(request));
    
                

如果我理解正确,您要做的是在显示选项卡时重新加载每个网格的内容?

然后,您可以在 onTabShow 事件中执行以下操作:

function onTabShow(e) 
    var tab = $('#tabstrip > ul > li.k-item.k-state-default.k-tab-on-top.k-state-active > span.k-link');
    if (tab !== null) 
        var tabText = tab.text();
        var hashId = '#grid';
        if (tabText == 'All') 
            hashId = '#grid';
         else if (tabText == 'Electric') 
            hashId = '#gridElectric';
         else if (tabText == 'Gas') 
            hashId = '#gridGas';
        
        var grid = $(hashId).data('kendoGrid');
        console.log('onTabShow $(hashId) = ');
        console.log(grid);
        if (grid !== undefined) 
            grid.dataSource.read();
        
    
;

【讨论】:

感谢您提供有关数据绑定的说明。那是个问题。您可能已经猜到了,我的代码来自 Telerik 的 Kendo Grid 示例,我的事件部分来自他们的事件示例。 你成功了吗?如果我的帖子对你有帮助,别忘了标记为正确答案:)

以上是关于在 ASP.NET MVC 上使用 Kendo Grid 更改数据的主要内容,如果未能解决你的问题,请参考以下文章

带有大型数据源的 Kendo Chart 的 Ajax 请求上的 ASP.NET MVC 应用程序?

使用 Kendo UI Asp.net mvc core 未显示图表组件

InCell 编辑模式下的 Kendo UI ASP.Net MVC ForeignKey 列 DataSource

ASP.NET MVC - Kendo Grid 慢分页

在 Kendo Scheduler 自定义模板中绑定 DropDownList(ASP.NET MVC Wrapper 版本)

如何使用 ASP.NET MVC 在 Kendo UI Grid 中实现 N 级嵌套层次结构