我一直在使用asp.net网络表单,并且我认为我喜欢的是与生成的标记的一致性,例如如果为TextField创建复合控件,则可以在单个类中控制生成的标记,并且不要破坏SRP:
<form:textfield id="firstName" runat="server" required="true" label="First Name" />
我是你要手动生成标记,它可能看起来像这样:
<label for="firstName" id="lbl_firstName">Name <span class="required">*</span></label>
<input id="firstName" name="firstName" type="text" value="" />
问题是什么时候想要改变一些东西,例如添加包装div或移动跨度。在最坏的情况下,您必须编辑数千个视图。
这就是我真正喜欢MVC Contrib FluentHtml的原因。
<%= this.TextBox(x => x.Message.PostedBy).Class("required").Label("Name") %>
我的问题是你认为为上面的代码行添加包装div的最佳方法是什么?我认为由于上述论点,手写不是一种选择?也许扩展TextBox:MvcContrib.FluentHtml.Elements.TextInput?
答案 0 :(得分:2)
你在MvcContrib项目中检查了InputBuilder吗?它也用在Codecampserver中。看看,我想你会喜欢它。
答案 1 :(得分:1)
老实说,我不认为你给出的例子适用于现实世界。文本框是文本框。如果你需要,你可以渲染一个
如果您需要更加“复杂”的控件,例如包含在div
标记中的文本框,那么您可以获得部分视图。
例如,型号:
public class CustomControlModel {
public string Name { get; set; }
public string Value { get; set; }
public string Class { get; set; }
public bool WrapInDivTag { get; set; }
//you get the idea
}
自定义控制:
<%@ Control Inherits="System.Web.Mvc.ViewUserControl<CustomControlModel>" %>
<%if (Model.WrapInDivTag) {%> <div> <% } %>
<%=Html.TextBox(Model.Name, Model.Value, new { @class = Model.Class })%>
<%if (Model.WrapInDivTag) {%> </div> <% } %>
渲染时:
<%Html.RenderPartial("CustomControl",
new CustomControlModel { Name = "name", WrapInDivTag = true }); %>
这是一个非常简单的例子,但我希望它能解释为什么我建议部分观点。不要忘记您可以公开另一个属性来获取要呈现的标记等。
答案 2 :(得分:0)
InputBuilders是一个选项。使用FluentHtml,您可以创建一个自定义元素,如下所示:
public class TextBoxInContainer : TextInput<TextBox>
{
public TextBoxInContainer (string name) : base(HtmlInputType.Text, name) { }
public TextBoxInContainer (string name, MemberExpression forMember, IEnumerable<IBehaviorMarker> behaviors) : base(HtmlInputType.Text, name, forMember, behaviors) { }
protected override ToString()
{
divBuilder = new TagBuilder(HtmlTag.Div);
divBuilder.InnerHtml = ToString();
return divBuilder.ToString(TagRenderMode.SelfClosing);
}
}
要在视图中使用此功能,您可以将IViewModelContainer扩展为:
public static MyTextBox TextBoxInContainer <T>(this IViewModelContainer<T> view, Expression<Func<T, object>> expression) where T : class
{
return new TextBoxInContainer (expression.GetNameFor(view), expression.GetMemberExpression(), view.Behaviors)
.Value(expression.GetValueFrom(view.ViewModel));
}
然后,如果要将容器更改为跨站点范围,则更改TextBoxInContainer的ToString方法。