【问题标题】:ASP.NET MVC: How do other people apply conditional CSS classes?ASP.NET MVC:其他人如何应用条件 CSS 类?
【发布时间】:2011-11-16 09:56:30
【问题描述】:

假设我有两个 CSS 样式,分别称为 januarytuesday。我想将它们应用于我视图中的某些文本字段,具体取决于它是一月还是周二。

选项 A:在控制器中执行逻辑,并将样式放在 ViewData 中。

在控制器中:

if( month == Month.January) 
  ViewBag.UserNameCssStyles = "january";
if( today == Day.Tuesday )
  ViewBag.UserNameCssStyles += " tuesday";

在视图中:

@Html.TextBoxFor(model => model.UserName, new { @class = ViewBag.UserNameCssStyles }

选项 B:在控制器中执行逻辑并在视图中分配样式?

在控制器中:

ViewBag.IsJanuary = (month == Month.January);
ViewBag.IsTuesday = (today == Day.Tuesday);

在视图中:

@if (ViewBag.IsJanuary && !ViewBag.IsTuesday) 
{
  @Html.TextBoxFor(model => model.UserName, new { @class = "january" })
}
else if (!ViewBag.IsJanuary && ViewBag.IsTuesday)
{
  @Html.TextBoxFor(model => model.UserName, new { @class = "tuesday" })
}
else if(ViewBag.IsJanuary && ViewBag.IsTuesday)
{
  @Html.TextBoxFor(model => model.UserName, new { @class = "january tuesday" })
}
else
{
  @Html.TextBoxFor(model => model.UserName)
}

在我看来,这两种方式都不对。第一个选项使控制器与显示相关,并且还锁定了样式,因此在视图上工作的人无法更改它们,例如,添加第三个类。但第二个选项似乎很逻辑,因为它只是“愚蠢”的观点。

其他人通常如何做到这一点?

【问题讨论】:

    标签: asp.net css asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    选项 C: 在控制器中执行逻辑并在视图中分配样式,但方式更简单:

    在控制器中:

    ViewBag.IsJanuary = (month == Month.January);
    ViewBag.IsTuesday = (today == Day.Tuesday);
    

    在视图中:

    @string userNameClass = string.Empty;
    @userNameClass += ViewBag.IsJanuary ? "january " : "";
    @userNameClass += ViewBag.IsTuesday ? "tuesday " : "";
    
    @Html.TextBoxFor(model => model.UserName, new { @class = userNameClass })
    

    否则你的控制器会被视图问题污染。除非您是 google 并且每个字节都很重要,否则空类几乎是无害的。

    【讨论】:

    • 这是正确的答案,恕我直言。 UI 类的选择是视图的责任,而不是控制器。当控制器承担这个责任时,它很快就会导致代码膨胀。让 View 确定哪些类将应用于其上存在的控件……这是它的工作。
    【解决方案2】:

    选项 A - 绝对。

    所有的逻辑都应该放在控制器中。通过模型将所有必要的数据传递给视图是控制器的责任。

    使用switch 或创建<Month, string><Day, string> 的静态字典来存储映射,而不是多个if 语句(有点异味)。

    【讨论】:

      【解决方案3】:

      您是否考虑过使用 jQuery 来附加 css 类?控制器应该不知道 css 类名称,因为它打破了关注点分离设计原则。

      您要做的是根据日期改变样式,只要您对客户端浏览器上的日期而不是托管网站的服务器上的日期感兴趣,就可以使用 jQuery 轻松完成...

      例如在您的网站主 .js 文件中输入以下内容

      $(document).ready(function () {
          var today = new Date();
          if (today.getMonth() == 0) $(".dateStyle").addClass("january");
          if (today.getDay() == 2) $(".dateStyle").addClass("tuesday");
      });
      

      那么在你看来使用

      @Html.TextBoxFor(model => model.UserName, new { @class = "dateStyle" }
      

      如果您确实需要它根据服务器上的日期而有所不同,那么如果您想遵循这种方法,则需要通过 JSON 对象将存储在 ViewBag 中的值传递给 javascript。

      【讨论】:

      • 日期只是我想出的一个简单示例,旨在将这个问题提炼成一个小问题。实际问题是:有条件地将类应用于 HTML 元素:最好的方法是什么?
      • 好的,所以更多的问题是如何根据模型数据的变化来改变我的 CSS。然后,我会将显示逻辑放在视图中,即选项 B,但以与 Todd 建议的方式类似的方式构建 css 类名称。对我来说重要的是控制器不知道 css 类名。
      【解决方案4】:

      我知道这现在真的很老了 - 但我遇到了同样的问题,并且发现所有这些选项都很丑 - 特别是考虑到如果第一个条件为假,而第二个条件为真,你会留下类似的东西;

      class=" className"
      

      (注意类名前的空格)

      我创建了一个 HtmlHelper 来解决我的问题:

      public static IHtmlString ClassString(this HtmlHelper helper, Dictionary<string, bool> classes)
      {
          return new HtmlString(string.Join(" ", classes.Where(c => c.Value).Select(c => c.Key)));
      }
      

      为了一致性(如果需要单个条件类):

      public static IHtmlString ClassString(this HtmlHelper helper, string classString, bool condition)
      {
          return new HtmlString(condition ? classString : "");
      }
      

      这些可以按如下方式使用;

      @{
          var classes = new Dictionary<string, bool>() {
              { "january", month == Month.January },
              { "tuesday", today == Day.Tuesday }
          }
      }
      <div class="@Html.ClassString(classes)">...</div>
      // OR
      @Html.TextBoxFor(model => model.UserName, new { @class = Html.ClassString(classes) })
      // OR (for a single condition)
      <div class="@Html.ClassString("january", month == Month.January)">...</div>
      // OR
      @Html.TextBoxFor(model => model.UserName, new { @class = Html.ClassString("january", month == Month.January) })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-29
        • 1970-01-01
        • 1970-01-01
        • 2016-06-08
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 2021-03-04
        相关资源
        最近更新 更多