1

我一直在使用 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?

4

3 回答 3

2

你检查过 MvcContrib 项目中的 InputBuilder 吗?它也用于 Codecampserver。看看,我想你会喜欢的。

于 2009-10-24T12:03:23.773 回答
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 }); %>

这是一个非常简单的例子,但我希望它能解释为什么我建议使用部分视图。不要忘记您可以公开另一个属性来获取要渲染的标签等。

于 2009-10-24T12:07:06.233 回答
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 方法。

于 2009-11-10T17:16:41.930 回答