首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC视图中的DRY

MVC视图中的DRY
EN

Stack Overflow用户
提问于 2009-10-24 19:57:30
回答 3查看 539关注 0票数 1

我一直在使用SRP表单,我认为我喜欢的是与生成的标记的一致性,例如,如果你为TextField创建一个复合控件,你可以在单个类中控制生成的标记,而不会破坏asp.net:

代码语言:javascript
复制
<form:textfield id="firstName" runat="server" required="true" label="First Name" />

如果您要手动生成标记,它可能如下所示:

代码语言:javascript
复制
<label for="firstName" id="lbl_firstName">Name <span class="required">*</span></label>
<input id="firstName" name="firstName" type="text" value="" />

问题是什么时候想要改变一些东西,例如添加一个包装div或移动跨度。在最坏的情况下,你不得不编辑成千上万的视图。

这就是为什么我非常喜欢MVC Contrib FluentHtml的原因。

代码语言:javascript
复制
<%= this.TextBox(x => x.Message.PostedBy).Class("required").Label("Name") %>

我的问题是,您认为为上面的代码行添加包装div的最佳方式是什么?我认为手写不是一种选择,因为上面的争论?也许可以扩展TextBox : MvcContrib.FluentHtml.Elements.TextInput?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-24 20:03:24

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

票数 2
EN

Stack Overflow用户

发布于 2009-10-24 20:07:06

老实说,我不认为你给出的例子适用于现实世界。textbox就是textbox。如果你需要一个,你可以渲染一个。

如果您需要一个更“复杂”的控件,比如包装在div标记中的textbox,那么您可以为它提供一个局部视图。

例如,Model:

代码语言:javascript
复制
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
}

自定义控件:

代码语言:javascript
复制
<%@ 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> <% } %>

渲染时:

代码语言:javascript
复制
<%Html.RenderPartial("CustomControl", 
    new CustomControlModel { Name = "name", WrapInDivTag = true }); %>

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

票数 1
EN

Stack Overflow用户

发布于 2009-11-11 01:16:42

InputBuilders是一种选择。使用FluentHtml,您可以创建一个自定义元素,如下所示:

代码语言:javascript
复制
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,如下所示:

代码语言:javascript
复制
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方法。

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

https://stackoverflow.com/questions/1617795

复制
相关文章

相似问题

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