Kendo 嵌套网格在 asp.net MVC 应用程序中扩展行时绑定内部网格

Kendo nested grid bind inner grid when expand the row in asp.net MVC application

我正在实施一个 asp.net MVC 应用程序,其中包含一个带有嵌套数据网格的页面。目前,我正在使用单个复杂数据对象绑定数据并且它正在正确加载数据。

但问题是当内部网格有太多数据时,需要一些时间从数据库中获取数据并为所有行创建一个数据对象。

我需要做的是在用户展开所选行时获取并绑定内部网格数据。

<div class="panel panel-default">
     <div class="panel-body">
          <div id="purchase-order-grid"></div>
     </div>
</div>

$(document).ready(function () {
    
        $("#purchase-order-grid").kendoGrid({
        columns: [
            {
                field: "PurchaseOrderNumber",
                title: "Purchase Order",
                width: 80,               
                headerAttributes: { style: "text-align:center" },
                attributes: { style: "text-align:center" }
            },
            {
                field: "Store",
                title: "Store",
                width: 100,
                headerAttributes: { style: "text-align:center" },
                attributes: { style: "text-align:center" }
            }
        ],
        detailTemplate: '<div class="second-level-grid"></div>',
        detailInit: function (e) {
            e.detailRow.find(".second-level-grid").kendoGrid({
                dataSource: e.data.Products,
                columns: [
                    {
                        field: "PartNumber",
                        title: "Part",
                        width: 70
                    },
                    {
                        field: "Description",
                        title: "Description",
                        width: 150
                    }
                ]
            })
        },
        dataSource: {
            type: "json",
            transport: {
                read: {
                    url: "@Html.Raw(Url.Action("List", "PurchasingPurchaseOrder"))",
                    type: "POST",
                    dataType: "json",
                    data: additionalData
                }
            }
        }
    });    
}

function additionalData() {
           var data = {
                StoreId: $('#@Html.IdFor(model => model.StoreId)').val()
           };
           addAntiForgeryToken(data);
           return data;
}

[HttpPost]
public virtual IActionResult List(PurchaseOrderSearchModel model, DataSourceRequest command)
{
    int totalCount = 0;
    var purchaseOrder = _purchaseOrderService.GetPurchaseOrdersWithSearchOption(model, out totalCount, command.Page - 1, command.PageSize);

    return Json(new DataSourceResult { Data = purchaseOrder, Total = totalCount });
}

我终于找到了解决办法。添加完整代码以供将来参考。

  <div class="panel panel-default">
       <div class="panel-body">
          <div id="purchase-order-grid"></div>
       </div>
  </div>

  var expanded = {};
    var grid, id;

    $(document).ready(function () {
        var element = $("#purchase-order-grid").kendoGrid({
            dataSource: {
            type: "json",
            transport: {
                read: {
                    url: "@Html.Raw(Url.Action("List", "PurchasingPurchaseOrder"))",
                    type: "POST",
                    dataType: "json",
                    data: additionalData
                }
            },

            schema: {
                data: "Data",
                total: "Total",
                errors: "Errors"
            },

            error: function (e) {
                display_kendoui_grid_error(e);
                // Cancel the changes
                this.cancelChanges();
            },
            pageSize: @(defaultGridPageSize),
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
        },

            sortable: true,
            pageable: true,
            detailInit: detailInit,
            dataBound: function (e) {
                grid = this;
                grid.tbody.find("tr[role='row']").each(function () {
                    var id = grid.dataItem(this).PurchaseOrderNumber;

                    if (expanded.hasOwnProperty(id) && expanded[id]) {
                        grid.expandRow(this);
                    }
                });
            },
            detailExpand: function (e) {
                id = this.dataItem(e.masterRow).PurchaseOrderNumber;
                expanded[id] = true;
            },
            detailCollapse: function (e) {
                id = this.dataItem(e.masterRow).PurchaseOrderNumber;
                expanded[id] = false;
            },
            columns: [                   
                    {
                        field: "Store",
                        title: "Store",
                        width: 100,
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    },
                    {
                        field: "POCreatedOn",
                        title: "PO Created On",
                        width: 100,
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    },
                    {
                        field: "SalesOrderTotal",
                        title: "Sales Order Total",
                        width: 80,
                        headerAttributes: { style: "text-align:right" },
                        attributes: { style: "text-align:right" }
                    },
                    {
                        field: "TotalPOCost",
                        title: "Total PO Cost (€)",
                        width: 100,
                        headerAttributes: { style: "text-align:right" },
                        attributes: { style: "text-align:right" }
                    },
                    {
                        field: "ShipmentStatus",
                        title: "Shipment Status",
                        width: 100,                       
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    },
                    {
                        field: "PaymentStatus",
                        title: "Payment Status",
                        width: 90,
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    }
            ]
        });
    });

    function detailInit(e) {
        $("<div/>").appendTo(e.detailCell).kendoGrid({
            dataSource: {
                type: "json",
                transport: {
                    read: {
                        url: "@Html.Raw(Url.Action("GetPurchaseOrderByPurchaseOrderNumber", "PurchasingPurchaseOrder"))",
                        type: "POST",
                        dataType: "json",
                        data: nestedGridData(e.data.PurchaseOrderNumber)
                    }
                },

            schema: {
                data: "Data",
                total: "Total",
                errors: "Errors"
            },

                serverPaging: true,
                serverSorting: true,
                serverFiltering: true,
                pageSize: 5,
                filter: { field: "PurchaseOrderNumber", operator: "eq", value: e.data.PurchaseOrderNumber }
            },


            scrollable: false,
            sortable: true,
            pageable: true,
            columns: [                   
                    {
                        field: "Description",
                        title: "Description",
                        width: 150
                    },
                    {
                        field: "SalesOrderId",
                        title: "Order",
                        width: 80,
                        template:'#=formatSalesOrderIds(SalesOrderId)#',
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    },
                    {
                        field: "QuantityOrdered",
                        title: "Qty Order",
                        width: 70,
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    },
                    {
                        field: "QuantityDispatched",
                        title: "Qty Shipped",
                        width: 70,
                        headerAttributes: { style: "text-align:center" },
                        attributes: { style: "text-align:center" }
                    }
            ]
        });
    }

    function nestedGridData(purchaseOrderNumber) {
           var data = {
                    GoDirectlyToPurchaseOrderId: purchaseOrderNumber
           };
           addAntiForgeryToken(data);
           return data;
    }

public class PurchasingPurchaseOrderController 
{
  [HttpPost]
  public virtual IActionResult List(PurchaseOrderSearchModel model, DataSourceRequest command)
  {      
            int totalCount = 0;
            var purchaseOrder = GetPurchaseOrdersWithSearchOption(model, out totalCount, command.Page - 1, command.PageSize);

            return Json(new DataSourceResult { Data = purchaseOrder, Total = totalCount 
    });
  }

 [HttpPost]
 public virtual IActionResult GetPurchaseOrderByPurchaseOrderNumber(PurchaseOrderSearchModel model, DataSourceRequest command)
 {   
     int totalCount = 0;
     var products= GetPurchaseOrderByPurchaseOrderNumber(model, out totalCount, command.Page - 1, command.PageSize);

      return Json(new DataSourceResult { Data = products, Total = totalCount });
     }
}


 public class DataSourceRequest
    {       
        public DataSourceRequest()
        {
            this.Page = 1;
            this.PageSize = 10;
        }
        public int Page { get; set; }      
        public int PageSize { get; set; }
        public List<Sort> Sort { get; set; }
    }