Twitter bootstrap 3 创建HtmlTag控件时使用.WrapWith

Twitter bootstrap 3 创建HtmlTag控件时使用.WrapWith,twitter-bootstrap-3,fubumvc,Twitter Bootstrap 3,Fubumvc,我正在基于Fubu项目为基于不可避免的Twitter引导框架的应用程序创建一些HTML助手方法。对于大多数简单的控件,直接对HtmlTag进行子分类没有问题;但是,对于更复杂的控件(通常需要嵌套在div标记中),它会变得更复杂一些 例如,我有一个TextboxWidget,它是这样实现的: public class TextboxWidget : HtmlTag { public TextboxWidget() : base("input") { Attr("ty

我正在基于Fubu项目为基于不可避免的Twitter引导框架的应用程序创建一些HTML助手方法。对于大多数简单的控件,直接对HtmlTag进行子分类没有问题;但是,对于更复杂的控件(通常需要嵌套在div标记中),它会变得更复杂一些

例如,我有一个TextboxWidget,它是这样实现的:

public class TextboxWidget : HtmlTag
{
    public TextboxWidget() : base("input")
    {
        Attr("type", "text");
        AddClass("form-control");
        NoClosingTag();
    }
}
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")
这很简单。然后可以这样使用它(与其他一些扩展方法一起使用):

给出期望的结果

我的DatepickerWidget实现如下:

public class TextboxWidget : HtmlTag
{
    public TextboxWidget() : base("input")
    {
        Attr("type", "text");
        AddClass("form-control");
        NoClosingTag();
    }
}
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")
然后使用如下方式:

public class TextboxWidget : HtmlTag
{
    public TextboxWidget() : base("input")
    {
        Attr("type", "text");
        AddClass("form-control");
        NoClosingTag();
    }
}
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标记,但它永远不会在页面上转换为HTML


我真的想保持主输入元素作为控件的焦点元素,所以所有漂亮的HtmlTag扩展都挂断了小部件;我是否必须通过为控件中的每个单独元素公开修饰符来继续下去?

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

一个选项是从类中删除
WrapWith
行,稍后添加包装:

@Html.Bootstrap().Datepicker(m=>m.StartDate).数据绑定(“单击”,“fnProcessClick”).AddClass(“特价”).WrapWith(新DivTag().AddClass(“输入组”))

如果这很麻烦,您可以通过向类中添加方法来缩短它:

 public HtmlTag WrapWithInputGroup()
 {
    return WrapWith(new DivTag().AddClass("input-group"));
 }

@Html.Bootstrap().Datepicker(m => m.StartDate).DataBind("click", "fnProcessClick").AddClass("special-offer").WrapWithInputGroup()
另一个与您期望的原始类工作方式相同的选项是重写
ToString()


巨大的警告:在我快速而肮脏的测试中,这是可行的,但这可能与HtmlTags的原始设计背道而驰。我会谨慎地使用这个解决方案(直到/除非像Jeremy Miller这样的人出现在这里并说它是正确的解决方案)。

我喜欢ToString覆盖建议-我会让它转一转,看看它是如何进行的。我已经开始使用第一个示例中给出的内联WrapWith方法,但这只是在小部件使用的每个地方引入了大量重复。我没有考虑第二种方法,因此,如果第三种解决方案被认为不合适,那么这可能是一种合理的回退。令人烦恼的是,当该控件在另一个控件中实例化时,它不起作用,幽灵部分就会丢失。