Вы можете выполнить следующую порнографию на ваш взгляд:
@model IEnumerable<Foo>
<table>
@foreach (var item in from i in Model.Select((value, index) => new { value, index }) group i.value by i.index / 3 into g select g)
{
<tr>
@foreach (var x in item)
{
<td><div class="productsFrame">@x.SomeProperty</div></td>
}
</tr>
}
</table>
или просто использовать вид модели и сделать группировку в своем действии контроллера, который, очевидно, является то, что я бы рекомендовал вам.Единственный факт, что вам нужно сделать это, означает, что ваша модель представления не адаптирована к требованиям вашего представления, то есть сгруппировать результаты по 3. Так что адаптируйте ее.Не передавайте IEnumerable<Foo>
на ваш взгляд.Передайте IEnumerable<MyViewModel>
, где, очевидно, MyViewModel будет содержать необходимую группировку, чтобы в ваших представлениях вы могли просто выполнять циклы или, поскольку я ненавижу писать циклы for и foreach в представлениях, просто использовать шаблоны отображения.Они будут заботиться обо всем, и ваш взгляд будет просто выглядеть следующим образом:
<table>
@HtmlDisplayForModel()
</table>
Выглядит лучше, чем первоначальная порнография не так
В соответствии с просьбой в разделе комментариевВот как я мог бы реализовать это, используя модели представлений.
Поскольку всегда в приложении ASP.NET MVC, вы начинаете с определения моделей представления, которые будут отражать требования вашего представления (что я повторяюявляются: показать таблицу с 3 столбцами):
public class ItemViewModel
{
public string Title { get; set; }
}
public class MyViewModel
{
public IEnumerable<ItemViewModel> Items { get; set; }
}
затем вы переходите к контроллеру, который заполнит и передаст эту модель представления в представление:
public class HomeController : Controller
{
public ActionResult Index()
{
// Obviously in a real world application the data is your domain model
// and comes from a repository or a service layer depending on the complexity
// of your application. I am hardcoding it here for the
// purposes of the demonstration
var data = Enumerable.Range(1, 30).Select(x => new { Title = "title " + x });
var model =
from i in data.Select((value, index) => new { value, index })
group i.value by i.index / 3 into g
select new MyViewModel
{
Items = g.Select(x => new ItemViewModel { Title = x.Title })
};
return View(model);
}
}
и, наконец, вызапишите соответствующий вид (~/Views/Home/Index.cshtml
):
@model IEnumerable<MyViewModel>
<table>
@Html.DisplayForModel()
</table>
и шаблон отображения ~/Views/Home/DisplateTemplates/MyViewModel.cshtml
:
@model MyViewModel
<tr>
@Html.DisplayFor(x => x.Items)
</tr>
и, наконец, соответствующий шаблон отображения ~/Views/Home/DisplateTemplates/ItemViewModel.cshtml
:
@model ItemViewModel
<td>@Html.DisplayFor(x => x.Title)</td>
и на этом все.Простой, чистый, следуя рекомендациям и соглашениям.
Очевидно, чтобы продвинуться на шаг вперед, вы бы ввели AutoMapper , чтобы выполнить фактическое сопоставление между вашими моделями доменов и моделями представления, и вы получитес очень элегантным решением, которое будет выглядеть так:
public ActionResult Index()
{
IEnumerable<DomainModel> data = ...
var viewModel = Mapper.Map<IEnumerable<DomainModel>, IEnumerable<MyViewModel>>(data);
return View(viewModel);
}
или шаг вперед:
[AutoMap(typeof(IEnumerable<DomainModel>), typeof(IEnumerable<MyViewModel>))]
public ActionResult Index()
{
IEnumerable<DomainModel> data = ...
return View(data);
}
Теперь мы начинаем заниматься серьезным бизнесом.