Saya yakin ini cukup sederhana, saya sepertinya tidak dapat menemukan cara yang tepat untuk menampilkan nama tampilan item dalam daftar dalam model saya.
Model saya yang disederhanakan:
public class PersonViewModel
{
public long ID { get; set; }
private List<PersonNameViewModel> names = new List<PersonNameViewModel>();
[Display(Name = "Names")]
public List<PersonNameViewModel> Names { get { return names; } set { names = value; } }
}
dan Nama:
public class PersonNameViewModel
{
public long ID { get; set; }
[Display(Name = "Set Primary")]
public bool IsPrimary { get; set; }
[Display(Name = "Full Name")]
public string FullName { get; set; }
}
Sekarang saya ingin membuat tabel untuk menampilkan semua nama seseorang, dan mendapatkan DisplayNameFor FullName. Jelas,
@Html.DisplayNameFor(model => model.Names.FullName);
tidak akan berhasil, dan
@Html.DisplayNameFor(model => model.Names[0].FullName);
akan rusak jika tidak ada nama. Adakah 'cara terbaik' untuk mendapatkan nama tampilan di sini?
sumber
List<PersonNameViewModel>
Anda memilikiIEnumerable<PersonNameViewModel>
, maka itu juga aman untuk menggunakan ekspresimodel => model.Names.First().FullName
. Apakah ini benar? Yang mengatakan, saya pikir saya paling sukadummyModel
contoh terbaik dari ketiganya. Jika tidak, Anda dapat memiliki beberapa properti yang perlu Anda ketik atau tempelmodel.Names[0].
. Kemudian lagi, mungkin Anda harus mengubah bagian menjadi tampilan parsial yang menerimaList
atauIEnumerable
sebagai modelnya.FirstOrDefault()
bekerja dengan daftar kosong.Ada cara lain untuk melakukannya, dan saya rasa itu lebih jelas:
public class Model { [Display(Name = "Some Name for A")] public int PropA { get; set; } [Display(Name = "Some Name for B")] public string PropB { get; set; } } public class ModelCollection { public List<Model> Models { get; set; } public Model Default { get { return new Model(); } } }
Dan kemudian, dalam tampilan:
@model ModelCollection <div class="list"> @foreach (var m in Model.Models) { <div class="item"> @Html.DisplayNameFor(model => model.Default.PropA): @m.PropA <br /> @Html.DisplayNameFor(model => model.Default.PropB): @m.PropB </div> } </div>
sumber
Sebagai solusi alternatif, Anda dapat mencoba:
Ini akan berfungsi bahkan jika daftarnya kosong!
sumber
Saya suka solusi T-moty. Saya membutuhkan solusi menggunakan obat generik sehingga solusi saya pada dasarnya adalah ini:
public class CustomList<T> : List<T> where T : new() { public static async Task<CustomList<T>> CreateAsync(IQueryable<T> source) { return new CustomList<T>(List<T> list); //do whatever you need in the contructor, constructor omitted } private T defaultInstance = new T(); public T Default { get { return defaultInstance; } } }
Menggunakan ini dalam tampilan sama dengan contohnya. Saya membuat satu instance dari objek kosong jadi saya tidak membuat instance baru setiap kali saya mereferensikan Default .
Catatan, batasan new () diperlukan untuk memanggil T () baru . Jika kelas model Anda tidak memiliki kontraktor default, atau Anda perlu menambahkan argumen ke konstruktor, Anda dapat menggunakan ini:
private T defaultInstance = (T)Activator.CreateInstance(typeof(T), new object[] { "args" });
Tampilan akan memiliki baris @model seperti:
sumber
DisplayNameFor
tidak pernah benar-benar memanggilget
untuk properti, jadi tidak masalah jika Anda membuat sebuah instance.