Как я могу считать циклы в mvc3 в @foreach - PullRequest
5 голосов
/ 16 ноября 2011

Как я могу закрыть <tr> и открыть <tr> после 3 итераций цикла?У меня есть MVC 3 в .NET 4.0.Как я могу считать итерации цикла в MVC 3?

Текущий код:

@foreach (var articleOnFirstPage in Model.ArticlesOnFirstSite)
{

<tr>
    <td><div class="productsFrame"></div></td>
</tr>

}

Я хочу получить это:

<tr>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
    </tr>
<tr>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
    </tr>
<tr>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
    </tr>

Ответы [ 4 ]

5 голосов
/ 16 ноября 2011

Вы можете выполнить следующую порнографию на ваш взгляд:

@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);
}

Теперь мы начинаем заниматься серьезным бизнесом.

5 голосов
/ 16 ноября 2011

Первое, что приходит на ум, - это лучший цикл foreach Фила Хаака

Используя его, вы получаете индекс и можете использовать его как

<ol>
@Model.Each(@<li>Item @item.Index of @(Model.Count() - 1): @item.Item.Title</li>)
</ol>

То, что вы конкретно ищете, должно выглядеть примерно так:

@Model.ArticlesOnFirstSite.Each(@<td><div class="productsFrame"></div></td>@(@item.Index % 3 == 0 ? "</tr><tr>" : ""))
3 голосов
/ 16 ноября 2011

Нечто подобное может работать.

@{int i = 0;}
@foreach (var articleOnFirstPage in Model.ArticlesOnFirstSite)
{
    @if ((i++ % 3) == 0) {
        @if (i != 1) {
            @:</tr>
        }
        @:<tr>
    }

    @:<td><div class="productsFrame"></div></td>
}

@if (i != 0) {
    @:</tr>
}

И это грубое решение вашей проблемы.

Как и другие предлагали, и, как я предлагаю, вы должны изменить свою методологию: используйте модели представления, сгруппируйте элементы по 3.

О том, как правильно использовать шаблон модель-вид-контроллер, вы можете посмотреть в Интернете. http://msdn.microsoft.com/en-us/library/gg416514(v=vs.98).aspx - хорошее начало.

0 голосов
/ 11 ноября 2014

Как и другие говорили, лучшее и самое красивое решение, вероятно, состоит в группировке в контроллере, но это может сделать работу:

@for (int i = 0; i < Model.ArticlesOnFirstSite.Count; i += 3)
{
    <tr>
        @foreach (Article article in Model.ArticlesOnFirstSite.Skip(i).Take(3))
        {
            <td>@article.Title</td>
        }
    </tr>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...