在创建HtmlTag控件时使用.WrapWith

时间:2014-10-27 06:25:40

标签: twitter-bootstrap-3 fubumvc

我正在基于不可避免的Twitter Bootstrap框架为基于Fubu项目的HtmlTags library创建一些HTML Helper方法。对于大多数简单的控件,我没有直接对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扩展都会挂起小部件;我是否必须通过为控件中的每个元素公开修饰符来沿着路线displayed by Jimmy Bogard走下去?

1 个答案:

答案 0 :(得分:1)

WrapWith返回一个新的HtmlTag;在DatePickerWidget的实现中,它基本上被忽略了,而DatePickerWidget仍然只是你基于它的“输入”标签。

一种选择是从您的类中删除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的原始设计背道而驰。我会谨慎使用这个解决方案(直到/除非杰瑞米勒这样的人出现在这里,并说这是正确的解决方案)。