首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用HTML助手减少代码重复

使用HTML助手减少代码重复
EN

Stack Overflow用户
提问于 2012-01-24 01:16:40
回答 2查看 390关注 0票数 0

我有一个相当简单的数据审计web应用程序,用ASP.MVC编写,它有效地有两个相同模型的视图,用于不同的目的。

  1. 代理视图-由验证信息的人员填写的表单。此视图中窗体上的每个字段都有3个子字段:

a.原始值-调用之前来自数据库的值。

b.新价值

行动--

  • QC视图的一般指示--由审查代理视图中所做工作的人填写的表单。此视图中窗体上的每个字段都有5个子字段:

a.原始价值-与上述相同

b.代理价值-代理人在上述1b中提供的价值。

c. QC值-如果代理指定的值不正确,更正的“新值”。

d.代理行为-与上述相同,但仅在此视图中阅读

e. QC行动--如果代理人选择不当,则更正为“新行动”。

这两个视图之间唯一的区别是可用的子字段。我希望能够使用单个视图来表示两个视图,因为页面的总体结构是相同的,只需使用HTML助手来处理子字段中的差异。到目前为止,我有两个明显不同的帮手系列(目前在同一班,但可以分开):

代码语言:javascript
运行
复制
// Agent controls
public static MvcHtmlString AuditControl(this HtmlHelper htmlHelper, string id, string fieldLabel, MvcHtmlString editControl, string cssClass)
public static MvcHtmlString AuditControl(this HtmlHelper htmlHelper, string id, string fieldLabel, string editControl, string cssClass)
public static MvcHtmlString AuditControl<COMPLEX>(this HtmlHelper htmlHelper, string id, string fieldLabel, string cssClass) where COMPLEX : AbstractComplex, new()

// QC controls
public static MvcHtmlString ReviewControl(this HtmlHelper htmlHelper, string id, string fieldLabel, MvcHtmlString editControl, string cssClass)
public static MvcHtmlString ReviewControl(this HtmlHelper htmlHelper, string id, string fieldLabel, string editControl, string cssClass)
public static MvcHtmlString ReviewControl<COMPLEX>(this HtmlHelper htmlHelper, string id, string fieldLabel, string cssClass) where COMPLEX : AbstractComplex, new()

其中,第三个实现处理由多个数据(如全名、地址等)组成的更复杂的字段。

我考虑过的一个可能的解决方案是将不同类型的控件分离到实现公共接口的不同类中,然后将它们作为类型参数传递给更通用的HTML助手。我认为这是可行的,但是我需要知道视图应该使用哪个实现来绘制视图,这似乎是有问题的,因为它似乎模糊了view和Controller之间的界限。

一种似乎不那么吸引人的方法是从控制器传递一种管理标志,它将由泛型(在逻辑上不是泛型类型)工厂助手使用,并在其中构建逻辑,以了解要使用的方法系列。这将使模型和视图保持分离,但感觉很脏,因为HTML助手将不仅仅负责构建HTML。

这是打破MVC设计的关注点分离的合理情况,还是有更合适的解决方案?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-24 01:36:33

由于您使用的是MVC3,我建议对子字段使用子操作:

http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx

子操作允许您在视图中的控制器上执行操作,这将是一种更干净的方法。

票数 3
EN

Stack Overflow用户

发布于 2012-02-14 05:07:03

我能够相当简单地实现@SoWeLie提供的建议(我对它的理解)。它涉及到创建一个新的模型来容纳可能的控件属性的超集,并为每个不同的控件集绘制一个新的视图(一个用于审核,另一个用于审查)。它的问题在于最终的View是丑陋的:

代码语言:javascript
运行
复制
@Html.RenderAction("DrawControl", new { id = "ID" ... })
// Repeated for all of the overloads of DrawControl

每个Controller操作都包含如下内容:

代码语言:javascript
运行
复制
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);

我不知道如何让我的泛型助手在这个场景中工作,此外,我还想减少明显的代码重复,所以很快就变成了这样:

代码语言:javascript
运行
复制
@functions {
    public string DrawControl(string id, ...) 
    {
        return Html.Render("DrawControl", new { id = "ID" });
    }
    // Repeated for all of the overloads of DrawControl
}

@DrawControl("ID", ...)

有着相同的控制器动作。这方面的问题(完全忽略视图具有函数的事实)是,必须将@functions块包含在任何希望使用它们的视图中(该视图目前只有2,但很快就会达到5,谁知道我的前任将对此做什么)。我很快又重新编写了代码,这次是为了使帮助人员返回(通常保持视图、模型和控制器更改),最后得到如下结果:

查看:

代码语言:javascript
运行
复制
@(Html.DrawComplexControl<ProviderName>("id", ...))
@Html.DrawSimpleControl("id", ...)

主计长:

代码语言:javascript
运行
复制
// 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);
}

帮手:

代码语言:javascript
运行
复制
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<T>(this HtmlHelper htmlHelper, string id, ...) where T : AbstractComplex, new()
{
    // Build the required controls based on `T`

    return DrawControl(htmlHelper, id, ...);
}

当然,在那些能帮助情况的迭代之间还有大约六次迭代,但没有一次在必要的情况下进行。我相信现在还需要改进,但这是我到目前为止所做的。

这样做为View提供了一个非常简单的API来使用,而不必知道或关心实现,而且它只需稍微修改(至少)就可以满足我先前存在的API的所有需求。我不确定这是否是答案的结果,但它是功能性的,并提供了必要的简单性。

希望将来我的头痛能帮助到别人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8980944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档