Использование.WrapWith при создании элементов управления HtmlTag
Я создаю несколько методов HTML Helper на основе библиотеки HtmlTags проекта Fubu для приложения, основанного на неизбежной платформе Twitter Bootstrap. Для большинства простых элементов управления у меня не было проблем с прямым подклассом HtmlTag; однако, когда дело доходит до более сложных элементов управления, которые обычно должны быть вложены в тег div, он становится немного более сложным.
Например, у меня есть TextboxWidget, который реализован примерно так:
public class TextboxWidget : HtmlTag
{
public TextboxWidget() : base("input")
{
Attr("type", "text");
AddClass("form-control");
NoClosingTag();
}
}
что довольно просто. Затем его можно использовать следующим образом (с несколькими другими методами расширения):
@Html.Bootstrap().Textbox(m => m.FirstName).Data("bind", "Employee.FirstName")
дать желаемый результат.
Моя реализация DatepickerWidget выглядит примерно так:
public class DatepickerWidget : HtmlTag
{
public DatepickerWidget() : base("input")
{
Attr("type", "text");
Attr("role", "datepicker");
AddClasses("form-control", "datepicker");
Data("dateformat", "dd/mm/yy");
Button = new HtmlTag("span").AddClass("input-group-addon");
var icon = new HtmlTag("i").AddClass("icon-calendar");
Button.Append(icon);
Append(Button);
WrapWith(new DivTag().AddClass("input-group"));
}
}
который затем используется так:
@Html.Bootstrap().Datepicker(m => m.StartDate).DataBind("click", "fnProcessClick").AddClass("special-offer")
но по какой-то причине тег div-обертки не отображается. Если я напишу несколько модульных тестов для элемента управления, то смогу увидеть тег div в объектной модели (в свойстве Parent), но он просто никогда не превращается в HTML на странице.
Я действительно хочу сохранить основной элемент ввода в качестве основного элемента управления, поэтому все красивые расширения HtmlTag свисают с виджета; мне придется идти по маршруту, указанному Джимми Богардом, выставляя модификаторы для каждого из отдельных элементов в элементе управления?
1 ответ
WrapWith
возвращает новый HtmlTag; в вашей реализации DatePickerWidget
в основном он просто игнорируется, а DatePickerWidget по-прежнему является просто тегом "input", на котором он основан.
Одним из вариантов будет отказаться от WrapWith
строки из вашего класса добавим обертку позже:
@Html.Bootstrap().Datepicker(m => m.StartDate).DataBind("click", "fnProcessClick").AddClass("special-offer").WrapWith(new DivTag().AddClass("input-group"))
Если это громоздко, вы можете сократить его, добавив для него метод класса:
public HtmlTag WrapWithInputGroup()
{
return WrapWith(new DivTag().AddClass("input-group"));
}
@Html.Bootstrap().Datepicker(m => m.StartDate).DataBind("click", "fnProcessClick").AddClass("special-offer").WrapWithInputGroup()
Другой вариант, который работает так, как вы ожидали, что ваш оригинальный класс будет работать, - это переопределение ToString()
:
public class DatepickerWidget2 : HtmlTag
{
public DatepickerWidget2()
: base("input")
{
Attr("type", "text");
Attr("role", "datepicker");
AddClasses("form-control", "datepicker");
Data("dateformat", "dd/mm/yy");
var Button = new HtmlTag("span").AddClass("input-group-addon");
var icon = new HtmlTag("i").AddClass("icon-calendar");
Button.Append(icon);
Append(Button);
}
public override string ToString()
{
return WrapWith(new DivTag().AddClass("input-group")).ToString();
}
}
Огромное, огромное предостережение: в моем быстром и грязном тестировании это работает, но это может противоречить оригинальному дизайну HtmlTags. Я бы использовал это решение с осторожностью (до тех пор, пока кто-нибудь, например Джереми Миллер, не появится здесь и не скажет, что это правильное решение).