Вопрос
Я много работал с asp.net веб-формами, и мне кажется, что мне нравится в них согласованность с сгенерированной разметкой, напримересли вы создаете составной элемент управления для текстового поля, вы можете управлять сгенерированной разметкой в одном классе, например, и не нарушать 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 для приведенной выше строки кода?Я думаю, что писать от руки - это не вариант из-за приведенных выше аргументов?Возможно, расширение текстового поля :MvcContrib.FluentHtml.Elements.Ввод текста?
Решение
вы проверяли InputBuilder в проекте MvcContrib?он также используется в Codecampserver.взгляните, и я думаю, вам это понравится.
Другие советы
Честно говоря, я не думаю, что приведенный вами пример применим к реальному миру.Текстовое поле - это текстовое поле.Если вам это нужно, вы создаете его сами.
Если вам нужен более "сложный" элемент управления, такой как текстовое поле, завернутое в 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 }); %>
Это очень простой пример, но я надеюсь, что он объясняет, почему я предложил частичные просмотры.Не забывайте, что вы можете предоставить другое свойство, чтобы узнать, какой тег отображать и т.д.
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.