Bagaimana cara menambahkan kelas css kedua dengan nilai kondisional dalam silet MVC 4

149

Sementara Microsoft telah membuat beberapa render atribut html secara otomatis di MVC4 silet, saya butuh waktu cukup lama untuk mengetahui cara membuat kelas css kedua pada suatu elemen, berdasarkan pada ekspresi pisau cukur bersyarat. Saya ingin membaginya dengan Anda.

Berdasarkan properti model @ Model.Details, saya ingin menampilkan atau menyembunyikan item daftar. Jika ada detail, div harus ditampilkan, jika tidak, itu harus disembunyikan. Menggunakan jQuery, yang perlu saya lakukan adalah menambahkan pertunjukan kelas atau menyembunyikan, masing-masing. Untuk keperluan lain, saya juga ingin menambahkan kelas lain, "detail". Jadi, mark-up saya seharusnya:

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

Di bawah ini, saya menunjukkan beberapa upaya gagal (mark-up yang dihasilkan dengan asumsi tidak ada detail).

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

akan membuat ini: <div class="details" hide="">.

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

akan membuat ini: <div class=""details" hide&quot;="">.

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

akan membuat ini: <div class="'details" hide&#39;="">.

Tidak ada yang benar mark-up.

R. Schreurs
sumber
Semua solusi pertama Anda akan berhasil jika Anda membungkusnya dalam contoh baru MvcHtmlString atau menggunakan Html.Raw
Kyle

Jawaban:

301

Saya percaya bahwa masih ada dan logika yang valid pada pandangan. Tetapi untuk hal-hal semacam ini saya setuju dengan @BigMike, lebih baik ditempatkan pada model. Setelah mengatakan bahwa masalah dapat diselesaikan dengan tiga cara:

Jawaban Anda (dengan asumsi ini berfungsi, saya belum mencoba ini):

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

Opsi kedua:

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

Opsi ketiga:

<div class="@("details " + (Model.Details.Count>0 ? "show" : "hide"))">
von v.
sumber
2
Saya menerima ini sebagai jawabannya, karena ia menawarkan lebih banyak opsi daripada saya.
R. Schreurs
18
Opsi 2 menyebabkan kesalahanThe "div" element was not closed
intrepidis
6
Tentu saja karena apa yang ditulis di sini bukan kode lengkap tetapi bagian dari kode yang dimaksud. Siapa yang tahu berapa banyak elemen lain dalam div;)
von v.
Tidak bekerja untuk saya. Saya mendapatkan kesalahan ini'ClubsModel' does not contain a definition for 'ClubsFilter' and no extension method 'ClubsFilter' accepting a first argument of type 'ClubsModel' could be found (are you missing a using directive or an assembly reference?)
Martin Erlic
Bagaimana masalah Anda terkait dengan pertanyaan yang diposting?
von v.
69

Ini:

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

akan membuat ini:

    <div class="details hide">

dan mark-up yang saya inginkan.

R. Schreurs
sumber
1
Saya tidak suka memiliki logika dalam pandangan, bahkan jika itu logika sepele, saya lebih suka menggunakan objek ModelView dengan metode getDetailClass ().
BigMike
29
Secara pribadi saya lebih suka logika sepele, memiliki metode getDetailCssClass berarti bahwa Model Anda mengetahui View Anda, memecah abstraksi itu. Saya akan menambahkan metode HasDetails ke Model untuk mengurangi logika yang diperlukan dalam tampilan, kemudian meninggalkan logika kelas css ke tampilan, itu berarti Anda tidak perlu membuang sampah pandangan @Model.Details.Count > 0. misalnya<div class="details @(@Model.HasDetails ? "show" : "hide")">
Chris Diver
26

Anda dapat menambahkan properti ke model Anda sebagai berikut:

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

dan kemudian tampilan Anda akan lebih sederhana dan tidak mengandung logika sama sekali:

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

Ini akan berfungsi bahkan dengan banyak kelas dan tidak akan membuat kelas jika itu nol:

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

dengan 2 bukan null properti akan merender:

    <div class="class1 class2"/>

jika class1 adalah nol

    <div class=" class2"/>
disinkronkan
sumber
11
Saya pikir lebih baik membiarkan pandangan mendefinisikan hal-hal seperti kelas css. Ingatlah bahwa tampilan harus dapat dimodifikasi secara deply (atau bahkan diganti) tanpa itu memengaruhi View Model
tobiak777
1
Meskipun saya setuju dengan reddy secara umum, mungkin ada kasus di mana itu dapat dibenarkan untuk melakukannya dengan cara yang disinkronkan. Saya melakukannya persis seperti itu. Dalam kasus saya, saya mengandalkan objek ViewModel yang penuh dengan informasi untuk menampilkan tampilan, itu bukan hanya objek data.
Gonzalo Méndez
1
Saya akan menggunakannya seperti ini jika ada lebih dari 2 hasil. Misalnya untuk 5 kelas yang mungkin. Daripada itu akan berantakan untuk tetap terlihat.
Mateusz Migała
1
Pemandangannya adalah tempat yang tepat. Memformatnya dengan baik sebagai tugas variabel dalam blok kode dan itu tidak akan berantakan.
Tom Blodget
3

Anda dapat menggunakan fungsi String.Format untuk menambahkan kelas kedua berdasarkan kondisi:

<div class="@String.Format("details {0}", Details.Count > 0 ? "show" : "hide")">
Chetan Gaonkar
sumber