我能够非常简单地实现(我的解释)@SoWeLie提供的建议。它涉及创建一个新模型来容纳可能的控件属性的超集,并为每个不同的控件集绘制一个新视图(一个用于审计,一个用于审阅)。它的问题是生成的View API很难看:
@Html.RenderAction("DrawControl", new { id = "ID" ... })
// Repeated for all of the overloads of DrawControl
并且每个Controller操作都包含以下内容:
public ActionResult DrawControl(string id, ...)
{
// FieldControl being the name of my Model
var viewModel = new FieldControl() { ID = id, ... };
if (shouldRenderAudit)
return PartialView("AuditControl", viewModel);
else
return PartialView("ReviewControl", viewModel);
我无法弄清楚如何让我的通用帮助程序在这种情况下工作,此外,我想删除减少明显的代码重复,所以这很快就变成了:
@functions {
public string DrawControl(string id, ...)
{
return Html.Render("DrawControl", new { id = "ID" });
}
// Repeated for all of the overloads of DrawControl
}
@DrawControl("ID", ...)
使用相同的控制器操作。这个问题(忽略View完全具有函数的事实)是@functions块必须包含在任何想要使用它们的视图中(目前只有2个但很快就会气球化)到5,谁知道我的前任会对此做些什么)。我再次快速重新编写代码,这次是为了恢复帮助程序(通常保持视图,模型和控制器的更改),最后结束了这个:
查看:
@(Html.DrawComplexControl("id", ...))
@Html.DrawSimpleControl("id", ...)
控制器:
// One common action that is used to determine which control should be drawn
public ActionResult DrawControl(FieldControl model)
{
if (shouldRenderAudit)
return PartialView("AuditControl", model);
else
return PartialView("ReviewControl", model);
}
助手:
public static MvcHtmlString DrawControl(this HtmlHelper htmlHelper, string id, ...)
{
var model = new FieldControl() { ID = id, ... };
return htmlHelper.Action("DrawControl", model);
}
public static MvcHtmlString DrawSimpleControl(this HtmlHelper htmlHelper, string id, ...)
{
return DrawSimpleControl(htmlHelper, id, ...);
}
public static MvcHtmlString DrawSimpleControl(this HtmlHelper htmlHelper, string id, ...)
{
// Set some defaults to simplify the API
return DrawControl(htmlHelper, id, ...);
}
public static MvcHtmlString DrawComplexControl(this HtmlHelper htmlHelper, string id, ...) where T : AbstractComplex, new()
{
// Build the required controls based on `T`
return DrawControl(htmlHelper, id, ...);
}
当然,在显示的情况之间有大约六个其他迭代来帮助这种情况,并且没有一个在必要的范围内进行。我确信还有待改进,但这是我到目前为止所做的。
这样做提供了一个非常简单的API供View使用,而不必知道或关心实现,它只需要很小的修改即可满足我原有API的所有要求(最后至少)。我不确定这是否是答案的结果,但它是功能性的,并提供了必要的简单性。
希望将来我的头痛会帮助别人。