СУХОЙ в MVC View - PullRequest
       39

СУХОЙ в MVC View

1 голос
/ 24 октября 2009

Я много работал с веб-формами 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="" />

Проблема в том, что когда вы хотите что-то изменить, например, добавить упаковочный тег или переместить интервал. В худшем случае вам нужно отредактировать тысячи просмотров.

Вот почему мне очень нравится MVC Contrib FluentHtml.

<%= this.TextBox(x => x.Message.PostedBy).Class("required").Label("Name") %>

Мой вопрос: что, по вашему мнению, является лучшим способом добавить упаковочный div для строки кода выше? Я думаю, что почерк не вариант из-за аргументов выше? Возможно расширение TextBox: MvcContrib.FluentHtml.Elements.TextInput?

Ответы [ 3 ]

2 голосов
/ 24 октября 2009

Вы проверяли InputBuilder в проекте MvcContrib? он также используется в Codecampserver. Посмотрите, и я думаю, вам понравится.

1 голос
/ 24 октября 2009

Честно говоря, я не думаю, что приведенный вами пример применим к реальному миру. Текстовое поле - это текстовое поле. Если вам нужно, вы делаете один.
Если вам нужен более «сложный» элемент управления, например текстовое поле, обернутое в тег 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 }); %>

Это очень простой пример, но я надеюсь, что он объясняет, почему я предложил частичные взгляды. Не забывайте, что вы можете выставить другое свойство, чтобы узнать, какой тег отображать и т. Д.

0 голосов
/ 10 ноября 2009

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));
}

Затем, если вы хотите изменить свой контейнер на промежуток по соседству, вы измените метод ToString TextBoxInContainer.

...