在 Kendo UI 中使用父网格的数据源设置子网格的数据源
Set datasouce of child grid using datasource of parent grid in Kendo UI
我有这个表格:
@*Some form fields here that accept startDate and endDate*@
<div>
<button id="searchButton">Search</button>
</div>
<div class="col-md-12 row">
@(Html.Kendo()
.Grid<ProjectName.DataModels.Models.Customer>()
.Name("CustomerGrid")
.Columns(columns =>
{
columns.Bound(e => e.CustomerId);
columns.Bound(e => e.SomeCustomerColumn);
})
.ClientDetailTemplateId("OrderDetails")
.AutoBind(false) // Don't load the data yet because I'll need to supply parameters for the fetch
.DataSource(dataSource => dataSource
.Ajax()
.Events(events=>events.Change("loadChildGrid"))
.PageSize(20)
.Model(model => model.Id("CustomerId", typeof(string)))
.Read(read => read.Action("GetCustomersAsync", "Customer").Data("passArguments"))
)
)
<script id="OrderDetails" type="text/kendo-tmpl">
@(Html.Kendo()
.Grid<ProjectName.DataModels.Models.Order>()
.Name("OrderDetails_#=CustomerId#")
.Columns(columns =>
{
columns.Bound(o => o.ProductName);
columns.Bound(o => o.SomeOrderColumn);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model=>model.Id("OrderId"))
.ServerOperation(false)
)
.AutoBind(false)
.ToClientTemplate()
)
</script>
</div>
<script type="text/javascript">
$("#searchButton").on("click", function () {
// Load the customerGrid here:
$("#CustomerGrid").data("kendoGrid").dataSource.read();
});
function passArguments() {
var startDate = $("#startdate").data("kendoDatePicker").value();
var endDate = $("#enddate").data("kendoDatePicker").value();
return {
start: startDate,
end: endDate
}
}
// QUESTION: How to load the child grid: OrderDetails_123 by using datasource from the parent grid?
// THIS IS WHAT I'VE TRIED SO FAR:
function loadChildGrid() {
var parentData = $("#CustomerGrid").data("kendoGrid").dataSource.data();
//Initialize the child grid
$.each(parentData, childDataFeeder);
}
function childDataFeeder(index, item) {
var childGridName = "#" + "OrderDetails_" + item.CustomerId;
var childGrid = childGridName.data("kendoGrid");
childGrid.dataSource.data(value.Orders)
}
</script>
以及 Customer
控制器中的一个方法:
public async Task<ActionResult> GetCustomersAsync([DataSourceRequest] DataSourceRequest request, DateTime start, DateTime end)
{
var customersWithOrders = GetDataForParentAndChildGrid(start, end);
return Json(customersWithOrders.ToDataSourceResult(request));
}
private List<Customer> GetDataForParentAndChildGrid(DateTime start, DateTime end)
{
var testData = new List<Customer>();
// Gets required data with those dates filter and perform some mathematical calculations
testData.Add(new Customer
{
CustomerId = "123",
SomeCustomerColumn = "Blah blah",
Orders = new List<Order>()
{
new Order{
OrderId = "123ABC",
CustomerId = "123",
SomeOrderColumn = "Blah Blah Blah"
}
}
});
return testData;
}
我的目标是使用主网格中已有的数据设置子网格的数据源。到目前为止我已经尝试过的是我已经将 Change
事件附加到触发 loadChildGrid
函数的主网格,我尝试从主网格中提取数据并将它的每个项目传递给 childDataFeeder
函数初始化子网格的数据源。这里的问题是,当它尝试这样做时,子网格尚不存在(因为它不是由 Kendo 创建的,直到用户单击主网格中的展开图标)。
您可以看到到目前为止我在 childDataFeeder
方法中尝试过的内容(没有任何成功)。
因此,非常感谢您对此的指导。
谢谢!
经过这么多小时的命中和试用,终于解决了。所以我把它贴在这里是为了在别人遇到类似问题时节省他们的时间:
我在主网格中添加了一个 DetailExpand
事件。并删除了 dataSource
上的 Change
事件。
@(Html.Kendo()
.Grid<ProjectName.DataModels.Models.Customer>()
.Name("CustomerGrid")
.Columns(columns =>
{
columns.Bound(e => e.CustomerId);
columns.Bound(e => e.SomeCustomerColumn);
})
.ClientDetailTemplateId("OrderDetails")
.AutoBind(false) // Don't load the data yet because I'll need to supply parameters for the fetch
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(model => model.Id("CustomerId", typeof(string)))
.Read(read => read.Action("GetCustomersAsync", "Customer").Data("passArguments"))
)
.Events(events => events.DataBound("dataBound").DetailExpand("onExpand"))
)
现在,每次我们在父网格中展开一行时,都会调用名为 onExpand
的回调函数。这是我现在将设置子网格的 dataSource
.
的地方
// Passing e is also important here because if you don't, this callback gets called
// for every row in the main grid (even when you don't expand them!)
function onExpand(e) {
var customerId = e.sender.dataItem(e.masterRow).CustomerId;
var orders = e.sender.dataItem(e.masterRow).Orders;
//Initialize the child grid as well
var childGridName = "#" + "OrderDetails_" + customerId;
var childGrid = $(childGridName).data("kendoGrid");
if (childGrid !== undefined) {
childGrid.dataSource.data(orders);
}
}
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
我使用 e.sender.dataItem(e.masterRow).PROPERTYNAME
从主行访问我需要的属性。
现在可以完美运行了!
我有这个表格:
@*Some form fields here that accept startDate and endDate*@
<div>
<button id="searchButton">Search</button>
</div>
<div class="col-md-12 row">
@(Html.Kendo()
.Grid<ProjectName.DataModels.Models.Customer>()
.Name("CustomerGrid")
.Columns(columns =>
{
columns.Bound(e => e.CustomerId);
columns.Bound(e => e.SomeCustomerColumn);
})
.ClientDetailTemplateId("OrderDetails")
.AutoBind(false) // Don't load the data yet because I'll need to supply parameters for the fetch
.DataSource(dataSource => dataSource
.Ajax()
.Events(events=>events.Change("loadChildGrid"))
.PageSize(20)
.Model(model => model.Id("CustomerId", typeof(string)))
.Read(read => read.Action("GetCustomersAsync", "Customer").Data("passArguments"))
)
)
<script id="OrderDetails" type="text/kendo-tmpl">
@(Html.Kendo()
.Grid<ProjectName.DataModels.Models.Order>()
.Name("OrderDetails_#=CustomerId#")
.Columns(columns =>
{
columns.Bound(o => o.ProductName);
columns.Bound(o => o.SomeOrderColumn);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model=>model.Id("OrderId"))
.ServerOperation(false)
)
.AutoBind(false)
.ToClientTemplate()
)
</script>
</div>
<script type="text/javascript">
$("#searchButton").on("click", function () {
// Load the customerGrid here:
$("#CustomerGrid").data("kendoGrid").dataSource.read();
});
function passArguments() {
var startDate = $("#startdate").data("kendoDatePicker").value();
var endDate = $("#enddate").data("kendoDatePicker").value();
return {
start: startDate,
end: endDate
}
}
// QUESTION: How to load the child grid: OrderDetails_123 by using datasource from the parent grid?
// THIS IS WHAT I'VE TRIED SO FAR:
function loadChildGrid() {
var parentData = $("#CustomerGrid").data("kendoGrid").dataSource.data();
//Initialize the child grid
$.each(parentData, childDataFeeder);
}
function childDataFeeder(index, item) {
var childGridName = "#" + "OrderDetails_" + item.CustomerId;
var childGrid = childGridName.data("kendoGrid");
childGrid.dataSource.data(value.Orders)
}
</script>
以及 Customer
控制器中的一个方法:
public async Task<ActionResult> GetCustomersAsync([DataSourceRequest] DataSourceRequest request, DateTime start, DateTime end)
{
var customersWithOrders = GetDataForParentAndChildGrid(start, end);
return Json(customersWithOrders.ToDataSourceResult(request));
}
private List<Customer> GetDataForParentAndChildGrid(DateTime start, DateTime end)
{
var testData = new List<Customer>();
// Gets required data with those dates filter and perform some mathematical calculations
testData.Add(new Customer
{
CustomerId = "123",
SomeCustomerColumn = "Blah blah",
Orders = new List<Order>()
{
new Order{
OrderId = "123ABC",
CustomerId = "123",
SomeOrderColumn = "Blah Blah Blah"
}
}
});
return testData;
}
我的目标是使用主网格中已有的数据设置子网格的数据源。到目前为止我已经尝试过的是我已经将 Change
事件附加到触发 loadChildGrid
函数的主网格,我尝试从主网格中提取数据并将它的每个项目传递给 childDataFeeder
函数初始化子网格的数据源。这里的问题是,当它尝试这样做时,子网格尚不存在(因为它不是由 Kendo 创建的,直到用户单击主网格中的展开图标)。
您可以看到到目前为止我在 childDataFeeder
方法中尝试过的内容(没有任何成功)。
因此,非常感谢您对此的指导。
谢谢!
经过这么多小时的命中和试用,终于解决了。所以我把它贴在这里是为了在别人遇到类似问题时节省他们的时间:
我在主网格中添加了一个 DetailExpand
事件。并删除了 dataSource
上的 Change
事件。
@(Html.Kendo()
.Grid<ProjectName.DataModels.Models.Customer>()
.Name("CustomerGrid")
.Columns(columns =>
{
columns.Bound(e => e.CustomerId);
columns.Bound(e => e.SomeCustomerColumn);
})
.ClientDetailTemplateId("OrderDetails")
.AutoBind(false) // Don't load the data yet because I'll need to supply parameters for the fetch
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(model => model.Id("CustomerId", typeof(string)))
.Read(read => read.Action("GetCustomersAsync", "Customer").Data("passArguments"))
)
.Events(events => events.DataBound("dataBound").DetailExpand("onExpand"))
)
现在,每次我们在父网格中展开一行时,都会调用名为 onExpand
的回调函数。这是我现在将设置子网格的 dataSource
.
// Passing e is also important here because if you don't, this callback gets called
// for every row in the main grid (even when you don't expand them!)
function onExpand(e) {
var customerId = e.sender.dataItem(e.masterRow).CustomerId;
var orders = e.sender.dataItem(e.masterRow).Orders;
//Initialize the child grid as well
var childGridName = "#" + "OrderDetails_" + customerId;
var childGrid = $(childGridName).data("kendoGrid");
if (childGrid !== undefined) {
childGrid.dataSource.data(orders);
}
}
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
我使用 e.sender.dataItem(e.masterRow).PROPERTYNAME
从主行访问我需要的属性。
现在可以完美运行了!