重构类似的CHTML,使用EditorFor和LabelFor呈现不同的属性

时间:2016-01-21 00:02:36

标签: c# asp.net-mvc razor

我正在构建一个包含很多关于剃刀视图的常用代码的项目。

示例:

<div class="form-group">
    @Html.LabelFor(model => model.LayoutFrontAmount, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => model.LayoutFrontAmount, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => model.LayoutFrontAmount, "", new { @class = "text-danger" })</span>
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.LayoutFrontBackAmount, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => model.LayoutFrontBackAmount, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => model.LayoutFrontBackAmount, "", new { @class = "text-danger" })</span>
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.LayoutTRC, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => model.LayoutTRC, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => model.LayoutTRC, "", new { @class = "text-danger" })</span>
    </div>
</div>

唯一改变的是Model的属性。

有没有办法用以下代码替换所有代码:

@TemplateName1(model => model.LayoutFrontAmount)
@TemplateName1(model => model.LayoutFrontBackAmount)
@TemplateName1(model => model.LayoutTRC)

2 个答案:

答案 0 :(得分:5)

您可以创建一个HtmlHelper扩展方法,该方法将为属性生成所有html,包括标签和输入元素

Right

然后您可以在using System; using System.Linq.Expressions; using System.Text; using System.Web.Mvc; using System.Web.Mvc.Html; namespace YourAssembly.Html { public static class BootstrapHelper { public static MvcHtmlString BootstrapEditorFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression) { MvcHtmlString label = LabelExtensions.LabelFor(helper, expression, new { @class = "control-label col-xs-12 col-sm-4 col-md-3" }); MvcHtmlString editor = EditorExtensions.EditorFor(helper, expression, new { htmlAttributes = new { @class = "form-control" } }); MvcHtmlString validation = ValidationExtensions.ValidationMessageFor(helper, expression, null, new { @class = "text-danger" }); // Build the input elements TagBuilder editorDiv = new TagBuilder("div"); editorDiv.AddCssClass("col-xs-4 col-sm-2 col-md-2 col-lg-1"); editorDiv.InnerHtml = editor.ToString(); // Build the validation message elements TagBuilder validationSpan = new TagBuilder("span"); validationSpan.AddCssClass("help-block"); validationSpan.InnerHtml = validation.ToString(); TagBuilder validationDiv = new TagBuilder("div"); validationDiv.AddCssClass("col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3"); validationDiv.InnerHtml = validationSpan.ToString(); // Combine all elements StringBuilder html = new StringBuilder(); html.Append(label.ToString()); html.Append(editorDiv.ToString()); html.Append(validationDiv.ToString()); // Build the outer div TagBuilder outerDiv = new TagBuilder("div"); outerDiv.AddCssClass("form-group"); outerDiv.InnerHtml = html.ToString(); return MvcHtmlString.Create(outerDiv.ToString()); } } } 文件中注册(表示您在视图中不需要web.config

@using ...

现在在您的主视图中,您可以使用以下3行代码生成问题中显示的所有html

<namespaces>
  <add namespace="System.Web.Mvc" />
  ....
  <add namespace="yourAssembly.Html " /> // add this
</namespaces>

如果您希望这可以在多个项目中重用,请在单独的dll中编译它,并在项目中添加对它的引用。

答案 1 :(得分:1)

取决于LayoutFrontAmount,LayoutFrontBackAmount和LayoutTRC中每个类型的类型。这些都是字符串吗?如果是这样,您可以使用一个公共视图文件来存储用于显示每个模板的模板,然后在主视图中使用@Html.Partial()显示每个模板:

MyView.cshtml

@model string
<div class="form-group">
    @Html.LabelFor(model => Model, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => Model, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => Model, "", new { @class = "text-danger" })</span>
    </div>
</div>

然后在主视图文件中,您可以按如下方式呈现LayoutFrontAmount,LayoutFrontBackAmount和LayoutTRC中的每一个:

@Html.Partial("MyView", Model.LayoutFrontAmount);
@Html.Partial("MyView", Model.LayoutFrontBackAmount);
@Html.Partial("MyView", Model.LayoutTRC);

如果它们是不同的类型,则会带来更大的挑战。