一个视图中的两个foreach循环

时间:2014-03-07 17:59:25

标签: c# asp.net-mvc razor

我有这个剃刀观点:

@using Order.Models
@model CategoriesViewModel

@{
    ViewBag.Title = "Categories";
}
@using (Html.BeginForm())
{
    <div class="panel-group">                   
        @foreach (var p in Model.Categories)
        {
          <div class="panel panel-default">
              <div class="panel-heading">
                  <h4 class="panel-title">
                      <a data-toggle="collapse" data-parent="#accordion" href="#@p.ID.ToString()">
       @p.Name
        </a>                     
                  </h4>
              </div>
               <div id="@p.ID.ToString()" class="panel-collapse collapse">
                   <div class="panel-body">  
          @foreach (var m in p.Items)                           
                       {
                          //put items data here
                       }                      
                   </div>
    </div>
              </div>     
        }        
    </div>
}

使用此viewmodel:

namespace Order.Models
{
    public class CategoriesViewModel
    {
        public IEnumerable<RestCategories> Categories;
        public List<List<RestItem>> Items;
    }
}

控制器操作是:

[HttpGet]
        public ActionResult Categories()
        {
            List<List<RestItem>> ItemsForCategory = new List<List<RestItem>>();
            API OneApi = new API();
            IEnumerable<RestCategories> itemsResult = API.GetCategoryResults("test", "test");
            if (itemsResult.Count() > 0)
            {                
                foreach (RestCategories cat in itemsResult)
                {
                    ItemsForCategory.Add(OneApi.GetItemsForCategory(ConfigurationManager.AppSettings["Key1"], ConfigurationManager.AppSettings["Key2"], cat.ID.ToString()));
                }
            }

            CategoriesViewModel modelCat = new CategoriesViewModel
            {
                Categories = itemsResult          
                .OrderBy(i=>i.Order),
                Items = ItemsForCategory                             
            };
            return View(modelCat);
        }

现在,我不确定这是否是正确的方法,但我想显示类别,并且在这些类别中我想要显示该类别中的项目。我可以在列表中获取所有项目,正如您在视图中看到的那样,我正在尝试遍历Items集合,但我无法从模型中获取Items属性。我也试过这种方法

  

@foreach(Model.Items.Where中的var m(n =&gt; n.CategoryId = p.ID))

但仍然没有。

3 个答案:

答案 0 :(得分:0)

您正在尝试访问可能不存在的值:

@foreach (var m in Model.Items.Where(n=>n.CategoryId = p.ID))

n.CategoryId 不存在,因为n正在引用Items列表的项目(也是列表)。

你的意思是:

 @foreach (var m in Model.Items.Where(n=>n.SOMETHING = p.ID))

我写了SOMETHING,因为你有一个列表列表,也许应该是:

public List<RestItem> Items;

然后n将拥有RestItem,您将能够访问其属性。

如果您需要的是每个类别的列表,那么您应该拥有的是:

namespace Order.Models
{
    public class CategoriesViewModel
    {
        public IEnumerable<RestCategories> Categories;
        public List<ListRestItem> Items;
    }
    public class ListRestItem
    {
       public int CategoryId;
       public List<RestItem> Items;

    }

这样你以前的代码就可以了。 希望它有所帮助

答案 1 :(得分:0)

不是在模型中有两个枚举,而是只有类别,它是关联的项目,然后将这些列表传递到视图中。

所以你的模型看起来像是:

public class CategoryViewModel
{
    public RestCategories Category;
    public List<RestItem> Items;
}

您的控制器会执行以下操作:

IEnumerable<RestCategories> categories = API.GetCategoryResults("test", "test");
var categoryModels = categories.OrderBy(c => c.Order)
                               .Select(c => new CategoryViewModel
                                       {
                                           Category = c,
                                           Items = OneApi.GetItemsForCategory(ConfigurationManager.AppSettings["Key1"], ConfigurationManager.AppSettings["Key2"], cat.ID.ToString())
                                       })
                               .ToList();
return View(categoryModels);

您的视图的模型类型为IEnumerable<CategoryViewModel>而不是CategoriesViewModel,并且会执行以下操作:

<div class="panel-group">                   
    @foreach (var m in Model)
    {
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#@m.Category.ID.ToString()">
                        @m.Category.Name
                    </a>                     
                </h4>
            </div>
            <div id="@m.Category.ID.ToString()" class="panel-collapse collapse">
                <div class="panel-body">  
                    @foreach (var i in m.Items)                           
                    {
                        //put items data here
                    }                      
                </div>
            </div>
        </div>     
    }        
</div>

答案 2 :(得分:0)

我的第一个答案的另一种选择是离开模型和视图类型,就像你现在拥有它一样。在控制器操作中,您要确保两个枚举在类别方面具有相同的顺序。然后,您可以在视图中将它们组合在一起:

<div class="panel-group">                   
    @foreach (var m in Model.Categories.Zip(Model.Items, (c, i) => new { Category = c, Items = I }))
    {
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#@m.Category.ID.ToString()">
                        @m.Category.Name
                    </a>                     
                </h4>
            </div>
            <div id="@m.Category.ID.ToString()" class="panel-collapse collapse">
                <div class="panel-body">  
                    @foreach (var i in m.Items)                           
                    {
                        //put items data here
                    }                      
                </div>
            </div>
        </div>     
    }        
</div>