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

问题描述

在我的控制器中,我有 1 个返回所有数据的 main 方法和 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 个选项卡显示“电力”和“天然气”:

            @(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",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",filtering and grouping is done client side
                                )
                                .AutoBind(false)
                                .Events(e => e.DataBound("onDataBound"))
                            </div>
                            </text>)
                        .Text("Gas");
                })
            )

在 jQuery 中,我有这 2 个函数适合我,但我无法弄清楚。 The first one onTabShow fires whenever a different tab is selected.它正在调用数据库,但它在 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);
                //    }
                //}
            }
        }
    }
};

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

解决方法

关于事件的问题。以下链接解释了这两个事件的作用。

在您的代码中,您无需在 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();
        }
    }
};