Asp.net mvc 基于对象数组的剑道网格多列组
我对Asp.net mvc 基于对象数组的剑道网格多列组,asp.net-mvc,razor,kendo-grid,Asp.net Mvc,Razor,Kendo Grid,我对MVC(和Kendo)相对较新,但我已经使用columns.Group功能设置了一个包含多列标题的网格 @(Html.Kendo().Grid<Result>() .Name("myGrid") .Columns(columns => { columns.Bound(c => c.ResultDateTime).Title("Date Time");
MVC
(和Kendo
)相对较新,但我已经使用columns.Group
功能设置了一个包含多列标题的网格
@(Html.Kendo().Grid<Result>()
.Name("myGrid")
.Columns(columns =>
{
columns.Bound(c => c.ResultDateTime).Title("Date Time");
foreach (Lot Lot in (Lot[])ViewBag.Lots)
{
columns.Group(group => group
.Title(Lot.LotNumber)
.Columns(info =>
{
info.Bound(Lot.Result.Count.ToString());
info.Bound(Lot.Result.Mean.ToString());
info.Bound(Lot.Result.SD.ToString());
}));
}
columns.Bound(c => c.StandardComment.Description).Title("Comment");
columns.Bound(c => c.ReviewComment.Description).Title("Review Comment");
columns.Command(command => { command.Destroy(); });
})
.Editable(editable => editable
.Mode(GridEditMode.InLine)
.DisplayDeleteConfirmation(true))
.Pageable()
.Navigatable()
.Sortable()
.Groupable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Read("ResultsAsync_Read", "ResultEntry")
.Destroy("ResultsAsync_Destroy", "ResultEntry")
)
)
运行此操作时,在尝试访问foreach
中的ViewBag.Lots
属性时,出现以下错误
NullReferenceException:对象引用未设置为
反对
有人知道我为什么会犯这样的错误吗?有没有更有效的方法来实现我的目标
编辑:
我不是使用ViewBag来保存批次
对象列表,而是使用它来保存整个列表
中可用的最大批次数。
我在船上听取了@ken2k的建议,并在控制器的Index()
功能中完成了此操作:
public async Task<IActionResult> Index()
{
QCTest test = new Models.Acusera.QCTest();
test.TestID = 3;
IEnumerable<Result> controlSets = await _manager.ReadAsync(test);
ViewBag.MaxLots = controlSets.Max(x => x.LotResults.Count);
return View("~/Views/Acusera/DataEntry/ResultEntry.cshtml");
}
公共异步任务索引()
{
QCTest test=新型号.Acusera.QCTest();
test.TestID=3;
IEnumerable controlset=wait_manager.ReadAsync(测试);
ViewBag.MaxLots=controlSets.Max(x=>x.LotResults.Count);
返回视图(“~/Views/Acusera/DataEntry/ResultEntry.cshtml”);
}
然后,我循环查看可用的最大批次数,并创建所需的列:
.Columns(columns =>
{
columns.Bound(c => c.ResultDateTime).Title("Date Time");
for (int i = 0; i < ViewBag.MaxLots; ++i)
{
columns.Group(group => group
.Title("Test")
.Columns(info =>
{
info.Bound(x => x.LotResults[i].Result.Count);
info.Bound(x => x.LotResults[i].Result.Mean);
info.Bound(x => x.LotResults[i].Result.SD);
}));
}
columns.Bound(c => c.StandardComment.Description).Title("Comment");
columns.Bound(c => c.ReviewComment.Description).Title("Review Comment");
columns.Command(command => { command.Destroy(); });
})
.Columns(Columns=>
{
columns.Bound(c=>c.ResultDateTime).Title(“日期时间”);
对于(int i=0;iGroup
.标题(“测试”)
.列(信息=>
{
绑定(x=>x.LotResults[i].Result.Count);
info.Bound(x=>x.LotResults[i].Result.Mean);
绑定(x=>x.LotResults[i].Result.SD);
}));
}
columns.Bound(c=>c.StandardComment.Description).Title(“Comment”);
columns.Bound(c=>c.ReviewComment.Description).Title(“审阅注释”);
Command(Command=>{Command.Destroy();});
})
这将导致网格显示如下所示:
因此,我成功地创建了显示数据所需的多标题列的数量。但是,我现在得到一个错误:
未捕获的TypeError:无法读取未定义的属性“Result”
您的
ResultsAsync\u Read
方法是一种异步方法,Kendo框架将通过javascript AJAX调用调用该方法,即在加载和呈现页面后调用该方法
这意味着当呈现页面时,,ViewBag.Lots
实际上为空,这会引发异常
您需要的是在加载页面时初始化该值,而不是在ResultsAsync\u Read
方法中。基本上:
public async Task<ActionResult> Index()
{
// Gets the values BEFORE rendering the view
IEnumerable<Result> controlSets = await _manager.ReadAsync(test);
// The ViewBag property will be available from the Razor view
ViewBag.Lots = controlSets.Select(x => x.LotResults);
// Returns the view that display the grid
return this.View();
}
公共异步任务索引()
{
//在呈现视图之前获取值
IEnumerable controlset=wait_manager.ReadAsync(测试);
//ViewBag属性将从Razor视图中可用
ViewBag.Lots=controlset.Select(x=>x.LotResults);
//返回显示网格的视图
返回这个.View();
}
记住MVC是如何工作的是很重要的。基本上,这些步骤是:
- 服务器通过…/索引路由接收请求
- 服务器执行Index()操作
- 当操作返回this.View()(相当于this.View(“Index”))时,它将呈现Index.cshtml razor视图(这意味着ViewBag在此不能为null)
- 如果以后执行AJAX调用,例如
,更改ViewBag不会有任何效果,因为页面已经呈现了。修改页面的唯一方法是返回一些JSON,并基于AJAX回调内部的JSON结果更改DOM(即使用jQuery/javascript)ResultsAsync\u Read
Lot
数组对象?@Sandman不太明白,页面加载后是否需要动态更改列(我是说使用AJAX)?是的,当用户做出不同的测试
选择时,需要从数据库中检索新值。Lot[]
长度可以从1到6不等,因此这意味着我需要根据所选的test
创建1到6列。@Sandman这样就更容易重新加载整个视图(因此1/您在索引操作2中填充了ViewBag/页面再次呈现新列)。如果您需要动态更改列(即通过AJAX而不重新加载整个页面),那么实现起来会有点困难。好的,我已经根据我对代码所做的一些编辑更新了我的问题。我现在使用ViewBag
来保存整个列表中可用的Lot
对象的最大数量,但遇到了另一个障碍。你有什么想法吗?提前谢谢
public async Task<ActionResult> Index()
{
// Gets the values BEFORE rendering the view
IEnumerable<Result> controlSets = await _manager.ReadAsync(test);
// The ViewBag property will be available from the Razor view
ViewBag.Lots = controlSets.Select(x => x.LotResults);
// Returns the view that display the grid
return this.View();
}