【问题标题】:ASP.NET MVC: 'Extend' Html.TextBox to conditionally have CSS value?ASP.NET MVC:“扩展”Html.TextBox 以有条件地具有 CSS 值?
【发布时间】:2009-08-18 07:00:45
【问题描述】:

我想扩展 ASP.NET MVC 的 TextBox,以便它有条件地切换其 CSS 值(基于模型中的数据)。但是,我不想将该逻辑放在我的视图中(通过有条件地更改 htmlAttributes/通过那里的方法调用),而是扩展类,这样我就不会弄乱我的视图。基本上我希望 TextBox 在创建时查看模型以查看它是否有一个具有自己名称的字典条目,然后查找关联的 CSS 值(如果找到)。

我遇到的问题是:

1) 如何扩展它? TextBox 本身已经是一个扩展方法而不是一个类,所以我不能“继承”?

2) 我如何将影响 TextBox 属性的条件从我的控制器方法传达给 TextBox?

【问题讨论】:

    标签: c# asp.net asp.net-mvc extension-methods html-helper


    【解决方案1】:

    您可能不应该将文本框耦合回模型。以一种方式拥有依赖关系总是更好的主意。从模型到视图。

    因此,间接的答案是有另一个可以接受枚举或布尔值的扩展方法,并根据这个方法添加或不添加类名。

    <%= Html.StyledTextBox("myField", ViewData["ShouldBeStyled"]) %>
    

    还有直接的答案。

    要扩展 ASP.NET MVC,您应该编写自己的扩展方法。您可以随时调用下划线扩展方法。所以你的代码可能看起来像:

    public static class MyCoolExtension
    {
      public static string TextBox(this HtmlHelper htmlHelper, string name)
      {
         // get data from htmlHelper.ViewData and call another extension methods of the HtmlHelper 
        var className = htmlHelper.ViewData["someClass"];
        return htmlHelper.TextBox("myField", "30", new { @class = className });
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以做的一件事是使用 ViewData 将所需的 CSS 类传递给您的视图,然后视图不需要知道您的逻辑来执行此操作。

      要回答您的具体问题,

      1:你是对的,你不能扩展它,但这里有两种选择:一种是完全避免扩展它的需要,并利用提供的东西(例如使用 ViewData),另一种是实施你自己的。如果您愿意,可以下载 MVC 源代码并直接从那里工作。

      2:考虑你的控制器中的一些东西:

      if (someCondition)
      {
          ViewData["someClass"] = "foo";
      }
      else
      {
          ViewData["someClass"] = "snazzle";
      }
      

      然后在你看来:

      <%= Html.TextBox("myField", "30", new { @class = ViewData["someClass"] }) %>
      

      祝你好运!
      -f!

      【讨论】:

      • 我已经知道 2 号并且想避免这种情况(正如我在问题中所写的那样)。我可能会尝试直接查看/使用 MVC 源代码,除非其他人有关于如何执行此操作的指针。
      【解决方案3】:

      根据它对您的重要性,您还可以使用 jQuery 来应用格式。选择特定的文本框非常容易。

      说“取决于它对您的重要性”,因为有一组用户禁用了 JavaScript(不能忽略),在这种情况下,格式将不会被应用。

      【讨论】:

        【解决方案4】:

        这就是为什么我对 MVC 团队决定在任何地方都使用字符串感到非常不满的原因。向文本框添加类不应该是 TextBox HtmlHelper 关心的问题,它应该是构建 HTML 的一个单独方面。这是使用语义模型定义 Html 的更好解决方案。我将在这里使用 TagBuilder,但我强烈建议您查看 FubuMvc 中包含的 HtmlTags 库。

        public TagBuilder TextBox(this HtmlHelper helper, string name, string value)
        {
           var tag = new TagBuilder("input");
           tag.MergeAttribute("type", "text");
           tag.MergeAttribute("name", name);
           tag.MergeAttribute("value", value);
           return tag;
        }
        

        现在,由于我们返回的是语义 (TagBuilder) 模型,因此我们可以继续修改模型,然后再将其转换为 HTML 文字。 ConditionallyAddClass 是一个可重用的扩展方法,它将一个类应用到任何 TagBuilder 模型:

        public TagBuilder ConditionallyAddClass<T>(this TagBuilder tag, string @class, T model, Func<T, bool> condition)
        {
           if(condition(model))
           {
              tag.AddCssClass(@class);
           }
           return tag;
        }
        

        在您看来,您现在可以这样做(假设 StyleAgeTextbox 是一个布尔属性):

        <%= Html.TextBox("Age", Model.Age).ConditionallyAddClass("customClass", Model, m => m.StyleAgeTextbox) %>
        

        视图引擎会自动调用 TagBuilder 上的 ToString() 以获取正确的 HTML。

        我希望这能给你一个基本的想法。当然有很多方法可以扩展它。您可以有一个标准的命名约定并使用dynamic 类型来绕过使用表达式,或者您可以有查找表或强类型整个事物以使用成员表达式(例如TextBoxFor(m => m.Age))。我更喜欢将整个东西移到像 Fubu does 这样的 html 约定框架中,但这可能超出了大多数项目的范围。

        【讨论】:

          猜你喜欢
          • 2010-09-15
          • 1970-01-01
          • 2020-04-28
          • 1970-01-01
          • 2016-05-07
          • 1970-01-01
          • 2012-07-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多