如何在Razor MVC 4中添加带有条件值的第二个CSS类

205

虽然Microsoft在razor MVC4中创建了一些自动渲染HTML属性, 但我花了很长时间才找到如何基于条件的razor表达式在元素上渲染第二个CSS类。我想与您分享。

基于模型属性@Model.Details,我想显示或隐藏列表项。如果有详细信息,则应显示一个div,否则应该隐藏。使用jQuery,我只需要分别添加一个类show或hide。出于其他目的,我还想添加另一个类“details”。因此,我的标记应为:

<div class="details show">[Details]</div> 或者 <div class="details hide">[Details]</div>

下面,我展示了一些失败的尝试(假设没有详细信息时的标记)。

这个:<div @(@Model.Details.Count > 0 ? "class=details show" : "class=details hide")>,

将会呈现出这个: <div class="details" hide="">

这个: <div @(@Model.Details.Count > 0 ? "class=\"details show\"" : "class=\"details hide\"")>

将会呈现出这个: <div class=""details" hide&quot;="">

这个: <div @(@Model.Details.Count > 0 ? "class='details show'" : "class='details hide'")>

将会呈现出这个: <div class="'details" hide&#39;="">

以上标记都不正确。


如果您将它们包装在新的MvcHtmlString实例中或使用Html.Raw,那么您的所有第一解决方案都可以工作。 - Kyle
5个回答

390

我认为观点仍然可以具有有效的逻辑性。但对于这种事情,我同意@BigMike的看法,最好将其放置在模型中。话虽如此,问题可以通过三种方式解决:

您的答案(假设这样做有效,我没有尝试过):

<div class="details @(@Model.Details.Count > 0 ? "show" : "hide")">

第二个选项:

@if (Model.Details.Count > 0) {
    <div class="details show">
}
else {
    <div class="details hide">
}

第三个选项:

<div class="@("details " + (Model.Details.Count>0 ? "show" : "hide"))">

2
我接受了这个答案,因为它提供的选项比我的更多。 - R. Schreurs
20
第二个选项导致错误“未关闭 'div' 元素”。 - intrepidis
12
当然会,因为这里所写的不是完整的代码,而只是引发问题的代码部分。谁知道 div 中还有多少其他元素呢 ;) - von v.
1
对我没用。我得到了这个错误:“'ClubsModel'不包含定义为'ClubsFilter'的内容,也没有接受类型为'ClubsModel'的第一个参数的扩展方法'ClubsFilter'(您是否缺少使用指令或程序集引用?)”。 - Martin Erlic
3
你的问题与发布的问题有何关联? - von v.

91

这个:

    <div class="details @(Model.Details.Count > 0 ? "show" : "hide")">

将呈现出这个:

    <div class="details hide">

并且这是我想要的标记。


1
我不喜欢在视图中编写逻辑,即使是微不足道的逻辑,我更喜欢使用一个带有getDetailClass()方法的ModelView对象。 - BigMike
36
个人而言,我更喜欢简单的逻辑。拥有一个getDetailCssClass方法意味着你的模型知道了你的视图,破坏了抽象层。我会在模型中添加一个HasDetails方法来减少视图中所需的逻辑,然后将CSS类的逻辑留给视图处理,这样你就不必在视图中添加@Model.Details.Count > 0了。例如:<div class="details @(@Model.HasDetails ? "show" : "hide")"> - Chris Diver

31

您可以按照以下方式向您的模型添加属性:

    public string DetailsClass { get { return Details.Count > 0 ? "show" : "hide" } }

然后你的视图会更简单,完全不包含逻辑:

    <div class="details @Model.DetailsClass"/>

即使有许多类,这也可以正常工作,并且如果为空,则不会呈现类:

    <div class="@Model.Class1 @Model.Class2"/>

含有两个非空属性的元素将呈现为:

    <div class="class1 class2"/>

如果 class1 为空

    <div class=" class2"/>

11
我认为最好让视图定义诸如CSS类之类的内容。请记住,应该能够在不影响视图模型的情况下对视图进行深度修改(甚至替换)。 - tobiak777
1
尽管我总体上同意 Reddy 的观点,但也可能存在情况,可以像 Syned 所说的那样做。我就是这样做的。在我的情况下,我依靠一个充满信息的 ViewModel 对象来呈现视图,它不仅仅是一个数据对象。 - Gonzalo Méndez
1
如果有超过2个结果,我会这样使用它。例如,对于5个可能的类别,将其保持在视图中会很混乱。 - cah1r
1
视图是正确的位置。将其格式化为代码块中的变量分配,它就不会凌乱。 - Tom Blodget

7
您可以使用String.Format函数根据条件添加第二个类:
<div class="@String.Format("details {0}", Details.Count > 0 ? "show" : "hide")">

0

在你的Razor代码中,更可重用的方法:

@functions {
    public static string Displayed(int count)
    {
        return count > 0 ? "show" : "hide";
    }
}

使用它:

<div class="@Displayed(Details.count)">Details content</div>

你可以在代码的任何地方重复使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接