我将首先定义一个视图模型(一如既往):
public class MyViewModel
{
public string LetterRange { get; set; }
public string[] Titles { get; set; }
}
然后是一个控制器动作,它将转换从某处获取模型,然后将其映射到视图模型。
备注:在这个例子中,我会将模型和视图模型之间的映射代码放在控制器动作中,但通常这应该放在单独的映射层中。例如,如果您使用AutoMapper,那可能是个好地方。
所以:
public ActionResult Index()
{
// The model could be of any form and come from anywhere but
// the important thing is that at the end of the day you will have
// a list of titles here
var model = new[]
{
"17\" Screen",
"100GB HD",
"10788 Firewire",
"Lock Cable",
"Monitor",
"Mouse",
"Keyboard",
"USB"
};
// Now let's map this domain model into a view model
// that will be adapted to the requirements of our view.
// And the requirements of this view is to group the titles
// in ranges of 3 letters of the alphabet
var viewModel = Enumerable
.Range(65, 26)
.Select((letter, index) => new
{
Letter = ((char)letter).ToString(),
Index = index
})
.GroupBy(g => g.Index / 3)
.Select(g => g.Select(x => x.Letter).ToArray())
.Select(range => new MyViewModel
{
LetterRange = string.Format("{0}-{1}", range.First(), range.Last()),
Titles = model
.Where(item => item.Length > 0 && range.Contains(item.Substring(0, 1)))
.ToArray()
})
.ToArray();
// Let's add those titles that weren't starting with an alphabet letter
var other = new MyViewModel
{
LetterRange = "Other",
Titles = model.Where(item => !viewModel.Any(x => x.Titles.Contains(item))).ToArray()
};
// and merge them into the final view model
viewModel = new[] { other }.Concat(viewModel).ToArray();
return View(viewModel);
}
现在在相应视图中剩下的就是根据要求显示标题:
@model MyViewModel[]
@foreach (var item in Model)
{
<h2>@item.LetterRange</h2>
foreach (var title in item.Titles)
{
<div>@title</div>
}
}
结果:
在将映射逻辑重构为映射层之后,相应的控制器操作可能如下所示:
public ActionResult Index()
{
// The model could be of any form and come from anywhere but
// the important thing is that at the end of the day you will have
// a list of titles here
DomainModel[] items = ...
// Now let's map this domain model into a view model
// that will be adapted to the requirements of our view.
var viewModel = Mapper.Map<IEnumerable<DomainModel>, IEnumerable<MyViewModel>>(items);
return View(viewModel);
}
清洁和干燥。