【发布时间】:2017-03-11 02:21:15
【问题描述】:
我的模型绑定到局部视图时遇到问题,我觉得必须有一种方法来做我想做的事。我想知道我的设计是否有缺陷,可能需要进行小的重构。
我的模型的一个非常简化(和抽象)的版本应该是这样的:
Public Class BaseClass
{
Public string Name { get; set; }
Public List<SomeClass> Things { get; set; }
}
Public Class DerivedClass : BaseClass
{
Public List<LineItem> Items { get; set; }
}
Public Class Library
{
Public List<LineItem> Items { get; set; }
}
Public Class LineItem
{
Public string Name { get; set; }
Public string Value { get; set; }
}
我有 BaseClass、SomeClass 和 LineItem 的编辑器模板。这些显示在 DerivedClass 的视图中,并通过向控制器提交更改来按预期工作。 LineItem 模板包含在 LineItemList 部分视图中,因为我打算将其用于 Library 的视图,并且不想重复所有该布局和 javascript。 LineItemList 部分视图包含在 Html.PartialView 的 DerivedClass 视图中,因为似乎没有办法为 List 类型创建编辑器模板。所以我的观点是这样的:
- 派生类视图
- 基类部分视图
- SomeClassPartialView
- LineItemListPartialView
- LineItemParialView
- 基类部分视图
当我提交表单时,控制器获取 BaseClass 和 SomeClass 列表的所有数据,但没有获取 LineItem 列表的数据。不同之处当然是一个使用 Html.EditorFor 和另一个 Html.PartialView 呈现。
重构类会很困难,因为它们必须向后兼容旧的 XML 格式以进行序列化,但我相信如果有必要我可以发挥一些神奇的作用。
正如 Chris Pratt 提到的,我忘记包含我的控制器方法:
Public ActionResult DerivedClassEditor()
{
Return View(New DerivedClass());
}
[HttpPost]
Public ActionResult DerivedClassEditor(DerivedClass dc)
{
// Do Stuff
}
我刚刚注意到在呈现的 Html 中,SomeClass 控件的名称为 SomeClass.[0].Name,而 LineItem 的名称为 [0].Name。我有一种感觉,这可能是问题的征兆。
而我的观点与此类似:
DerivedClassEditor
@model DerivedClass
@using (Html.BeginForm())
{
@Html.EditorFor(model => model)
@Html.Partial("LineItemListPartialView")
<input type="submit" />
}
LineItemListPartialView
@model List<LineItem>
<div name="Items">
@Html.EditorFor(model => model)
</div>
LineItemPartialView
@model LineItem
<div name="LineItem">
@Html.LabelFor(model => model.Name)
@Html.TextEditorFor(model => model.Name)
</div>
编辑:
我已经将问题缩小到这样一个事实,即当我使用@Html.EditorFor 加载其中一个列表时,它会将输入命名为Collection[index].Property,但是当我使用相同的调用动态添加一个列表时,它只是将输入命名为@987654331 @。是否有一种简单且可重用的方法让添加的新项目具有相同的命名结构?
【问题讨论】:
-
您对命名的最后评论表明您没有使用 EditorFor 渲染 LineItems,而是以某种方式使用部分。你真的应该包含你的视图代码,这样我们就可以看到发生了什么。
-
@ErikFunkenbusch,我将尝试添加我正在做的事情的简化版本。我不想让这个问题太长。
-
这里是github中的实际视图:github.com/melance/TheRandomizer/blob/Initial/…
-
您上面的代码与您实际视图中的代码不同,您遗漏了一个关键部分,即您使用子模型调用部分。这就是你的问题所在。执行此操作时,您会丢失生成名称中模型命名的层次结构。我建议您传递基本模型(或者更确切地说,将其留空,就像您在示例中所做的那样),然后让您的部分采用
DerivedClass模型而不是List<LineItem>模型。这里的问题是,partial 不理解它的模型是更大视图模型的一部分,因此它不会为它生成名称。 -
谢谢你,Erik,我该如何做这件事,并且仍然保持局部视图足够通用以处理 Library 对象?
标签: c# asp.net-mvc-5