对数据类型的复杂 html 视图进行标准化的首选方法是什么?
What is the preferred way to standardise complex html views for data types?
我有这样的代码,我在许多 MVC 编辑视图中重复使用。此示例是我们显示复选框的默认方式,但在其他输入类型中也发现了类似的重复。
<div class="form-group">
@Html.LabelFor(model => model.IsLive, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8 checkbox">
<div class="col-xs-1">
@Html.EditorFor(model => model.IsLive)
</div>
<div class="col-xs-10">
@Html.CheckboxLabelFor(model => model.IsLive)
</div>
</div>
<a class="infoonclick col-md-1" title="@Html.DisplayNameFor(model => model.IsLive)" data-content="@Html.DescriptionFor(model => model.IsLive)">
<span class="fa fa-info-circle"></span>
</a>
</div>
我想知道 DRY 和标准化的最佳方法是什么?
我想做类似@Html.DefaultCheckboxEditorFor(model => model.IsLive)
的事情
我尝试创建一个自定义的 HtmlHelper,但这似乎涉及太多的硬编码字符串而不是一个好主意。
相反,我觉得我应该为此使用 EditorTemplates,但我不太理解正确的语法。视图的模型是一个布尔值,但我需要获取 属性 特定的内容,例如显示名称和描述。
@model bool
<div class="form-group">
@Html.LabelFor(model => model.IsLive, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8 checkbox">
<div class="col-xs-1">
@Html.EditorFor(model => model.IsLive)
</div>
<div class="col-xs-10">
@Html.CheckboxLabelFor(model => model.IsLive)
</div>
</div>
<a class="infoonclick col-md-1" title="@Html.DisplayNameFor(model => model.IsLive)" data-content="@Html.DescriptionFor(model => model.IsLive)">
<span class="fa fa-info-circle"></span>
</a>
</div>
我有一个项目,我的大部分观点如下所示:
(这也适用于多层深层复杂对象,但不适用于任何类型的集合,如 IEnumerable,尽管可以对其进行修改)
<h3>Edit existing page</h3>
<div class="col-xs-12">
@using (Html.BeginForm("Edit", "Page", FormMethod.Post, new { role = "role" }))
{
@Html.EditorForModel()
<input type="submit" value="Save" class="btn btn-primary" />
}
</div>
我觉得这很酷。所以模型看起来像:
public class PageEditViewModel
{
[Editable(false)]
[DisplayName("Page Id")]
public Guid Id { get; set; }
[Editable(false)]
[DisplayName("Url to resource (format: '/my-resource' or '/sub/resource)'")]
public string Url { get; set; }
[Required]
[MaxLength(50, ErrorMessage = "Maximum Length of 50 Exceeded.")]
[DisplayName("Title for page (must match Url ex: 'My Resource' or 'Sub Resource'")]
public string PageTitle { get; set; }
[MaxLength(int.MaxValue, ErrorMessage = "Content Exceeded Maximum Length")]
[DataType(DataType.MultilineText)]
public string Content { get; set; }
}
我有一些编辑器模板:
\Views\Shared\EditorTemplates\multilinetext.cshtml
@model object
@{
var htmlAttributes = this.ViewData.ModelMetadata.GetHtmlAttributes();
}
<div class="form-group @Html.ErrorClassFor(m => m, "has-error")">
@Html.LabelFor(m => m, new { @class = "control-label" })
<div class="controls">
@Html.TextAreaFor(
m => m,
8, 8,
htmlAttributes)
@Html.ValidationMessageFor(m => m, null, new { @class = "help-block" })
</div>
</div>
这一切都神奇地与 object.cshtml 的修改版本一起工作:
@model object
@using System.Text;
@using System.Data;
@{
ViewDataDictionary viewData = Html.ViewContext.ViewData;
TemplateInfo templateInfo = viewData.TemplateInfo;
ModelMetadata modelMetadata = viewData.ModelMetadata;
System.Text.StringBuilder builder = new StringBuilder();
string result;
// DDB #224751
if (templateInfo.TemplateDepth > 2)
{
result = modelMetadata.Model == null ? modelMetadata.NullDisplayText
: modelMetadata.SimpleDisplayText;
}
foreach (var prop in modelMetadata.Properties.Where(pm =>
pm.ShowForEdit
//&& pm.ModelType != typeof(System.Data.EntityState)
&& !templateInfo.Visited(pm)
)
.OrderBy(pm => pm.Order))
{
//Type modelType = Model.GetType();
Type modelType = modelMetadata.ModelType;
System.Reflection.PropertyInfo pi = modelType.GetProperty(prop.PropertyName);
System.ComponentModel.DataAnnotations.DisplayAttribute attribute = pi.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.DisplayAttribute;
if (attribute != null
&& !string.IsNullOrWhiteSpace(attribute.GetGroupName()))
{
//builder.Append(string.Format("<div>{0}</div>", attribute.GetGroupName()));
builder.Append(Html.Partial("Partial-GroupName", attribute.GetGroupName()));
}
builder.Append(Html.Editor(prop.PropertyName, prop.TemplateHint ?? prop.DataTypeName).ToHtmlString());
}
result = builder.ToString();
}
@Html.Raw(result)
示例输出:
我的 EditFor 模板是 MacawNL BootstrapEditorTemplates 的版本(我与它没有隶属关系)。
我有这样的代码,我在许多 MVC 编辑视图中重复使用。此示例是我们显示复选框的默认方式,但在其他输入类型中也发现了类似的重复。
<div class="form-group">
@Html.LabelFor(model => model.IsLive, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8 checkbox">
<div class="col-xs-1">
@Html.EditorFor(model => model.IsLive)
</div>
<div class="col-xs-10">
@Html.CheckboxLabelFor(model => model.IsLive)
</div>
</div>
<a class="infoonclick col-md-1" title="@Html.DisplayNameFor(model => model.IsLive)" data-content="@Html.DescriptionFor(model => model.IsLive)">
<span class="fa fa-info-circle"></span>
</a>
</div>
我想知道 DRY 和标准化的最佳方法是什么?
我想做类似@Html.DefaultCheckboxEditorFor(model => model.IsLive)
我尝试创建一个自定义的 HtmlHelper,但这似乎涉及太多的硬编码字符串而不是一个好主意。
相反,我觉得我应该为此使用 EditorTemplates,但我不太理解正确的语法。视图的模型是一个布尔值,但我需要获取 属性 特定的内容,例如显示名称和描述。
@model bool
<div class="form-group">
@Html.LabelFor(model => model.IsLive, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8 checkbox">
<div class="col-xs-1">
@Html.EditorFor(model => model.IsLive)
</div>
<div class="col-xs-10">
@Html.CheckboxLabelFor(model => model.IsLive)
</div>
</div>
<a class="infoonclick col-md-1" title="@Html.DisplayNameFor(model => model.IsLive)" data-content="@Html.DescriptionFor(model => model.IsLive)">
<span class="fa fa-info-circle"></span>
</a>
</div>
我有一个项目,我的大部分观点如下所示: (这也适用于多层深层复杂对象,但不适用于任何类型的集合,如 IEnumerable,尽管可以对其进行修改)
<h3>Edit existing page</h3>
<div class="col-xs-12">
@using (Html.BeginForm("Edit", "Page", FormMethod.Post, new { role = "role" }))
{
@Html.EditorForModel()
<input type="submit" value="Save" class="btn btn-primary" />
}
</div>
我觉得这很酷。所以模型看起来像:
public class PageEditViewModel
{
[Editable(false)]
[DisplayName("Page Id")]
public Guid Id { get; set; }
[Editable(false)]
[DisplayName("Url to resource (format: '/my-resource' or '/sub/resource)'")]
public string Url { get; set; }
[Required]
[MaxLength(50, ErrorMessage = "Maximum Length of 50 Exceeded.")]
[DisplayName("Title for page (must match Url ex: 'My Resource' or 'Sub Resource'")]
public string PageTitle { get; set; }
[MaxLength(int.MaxValue, ErrorMessage = "Content Exceeded Maximum Length")]
[DataType(DataType.MultilineText)]
public string Content { get; set; }
}
我有一些编辑器模板:
\Views\Shared\EditorTemplates\multilinetext.cshtml
@model object
@{
var htmlAttributes = this.ViewData.ModelMetadata.GetHtmlAttributes();
}
<div class="form-group @Html.ErrorClassFor(m => m, "has-error")">
@Html.LabelFor(m => m, new { @class = "control-label" })
<div class="controls">
@Html.TextAreaFor(
m => m,
8, 8,
htmlAttributes)
@Html.ValidationMessageFor(m => m, null, new { @class = "help-block" })
</div>
</div>
这一切都神奇地与 object.cshtml 的修改版本一起工作:
@model object
@using System.Text;
@using System.Data;
@{
ViewDataDictionary viewData = Html.ViewContext.ViewData;
TemplateInfo templateInfo = viewData.TemplateInfo;
ModelMetadata modelMetadata = viewData.ModelMetadata;
System.Text.StringBuilder builder = new StringBuilder();
string result;
// DDB #224751
if (templateInfo.TemplateDepth > 2)
{
result = modelMetadata.Model == null ? modelMetadata.NullDisplayText
: modelMetadata.SimpleDisplayText;
}
foreach (var prop in modelMetadata.Properties.Where(pm =>
pm.ShowForEdit
//&& pm.ModelType != typeof(System.Data.EntityState)
&& !templateInfo.Visited(pm)
)
.OrderBy(pm => pm.Order))
{
//Type modelType = Model.GetType();
Type modelType = modelMetadata.ModelType;
System.Reflection.PropertyInfo pi = modelType.GetProperty(prop.PropertyName);
System.ComponentModel.DataAnnotations.DisplayAttribute attribute = pi.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.DisplayAttribute;
if (attribute != null
&& !string.IsNullOrWhiteSpace(attribute.GetGroupName()))
{
//builder.Append(string.Format("<div>{0}</div>", attribute.GetGroupName()));
builder.Append(Html.Partial("Partial-GroupName", attribute.GetGroupName()));
}
builder.Append(Html.Editor(prop.PropertyName, prop.TemplateHint ?? prop.DataTypeName).ToHtmlString());
}
result = builder.ToString();
}
@Html.Raw(result)
示例输出:
我的 EditFor 模板是 MacawNL BootstrapEditorTemplates 的版本(我与它没有隶属关系)。