在循环集合时,如何有效地将DropdownListFor绑定到嵌套类?

时间:2017-07-24 15:11:25

标签: c# asp.net-mvc razor

我正在努力让DropDownListFor工作。系统是时间表系统,相关的类是Week

public class Week
{
    public int WeekId { get; set; }
    public List<TimeEntry> TimeEntries { get; set; }
    public Week()
    {
        TimeEntries = new List<TimeEntry>();
    }
}

每个Week都包含TimeEntries的列表:

public class TimeEntry
{
    public int TimeEntryID { get; set; }
    public double MonHours { get; set; }
    public double TueHours { get; set; }
    public double WedHours { get; set; }
    public double ThuHours { get; set; }
    public double FriHours { get; set; }

    public int BillingStatusID { get; set; }
    [ForeignKey("BillingStatusID")]
    public virtual BillingStatus BillingStatus { get; set; }
}

每个TimeEntry都有BillingStatus(例如付费,待定,已开具发票):

public class BillingStatus
{
    public int BillingStatusID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }  
}

输入数据的方式来自WeekController。它有一系列行,一个用于数据库中的每个条目。还可以添加其他行,因此通过WeekController可以编辑/创建TimeEntries的双重功能:

enter image description here

但是,我无法让BillingStatus的DropDownLists工作。我想这是因为我通过循环渲染行。然而,由于BillingStatus不存储在Week类中,而是存储在TimeEntry类中,因此它变得更加复杂。 (所以我正在使用的控制器“降低一级”。

如果我对DropDownListFor控件中的列表进行硬编码,则可以正常工作:

@for (int i = 0; i < Model.TimeEntries.Count; i++)
{
    <div class="panel-body">
        <div class="index" style="display:none">@Model.TimeEntries[i].TimeEntryID</div>
        <div class="col-md-2">
            @Html.DropDownListFor(m => Model.TimeEntries[i].ClientID, (SelectList)ViewBag.ClientID, "Select...", new { style = "width:100%" })
        </div>
        <div class="col-md-2">
            @Html.DropDownListFor(m => Model.TimeEntries[i].TaskTypeID, (SelectList)ViewBag.TaskTypeID, "Select...", new { style = "width:100%" })
        </div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].MonHours, new { style = "width:100%", @class = "hours mon" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].TueHours, new { style = "width:100%", @class = "hours tue" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].WedHours, new { style = "width:100%", @class = "hours wed" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].ThuHours, new { style = "width:100%", @class = "hours thu" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].FriHours, new { style = "width:100%", @class = "hours fri" })</div>
        <div class="col-md-2">@Html.TextBoxFor(x => Model.TimeEntries[i].Comment)</div>
        <div class="col-md-1">
            @Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
                 new SelectList(new List<Object>{
                                    new { BillingStatusID = 0 , Name = "Pending"  },
                                    new { BillingStatusID = 1 , Name = "Invoiced"  },
                                    new { BillingStatusID = 2 , Name = "Paid"  },
                 }, "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))
        </div>
    </div>
}

但是,如果我尝试从数据库中填充它,它就会失败。我尝试过以下方法:

@Html.DropDownListFor(m => item.BillingStatusID, new SelectList(Model.TimeEntries[0].BillingStatuses, "BillingStatusId", "Name", "Select..."))

并且还尝试在WeekController中使用ViewBag:

@Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
                         new SelectList(ViewBag.BSID,
                        "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))

但这两种方法都不奏效。我还想确保每次渲染一行时都不会访问数据库,因为这似乎效率很低。

我想我想要做的就是得到这个:

new List<Object>{
    new { BillingStatusID = 0 , Name = "Pending"  },
    new { BillingStatusID = 1 , Name = "Invoiced"  },
    new { BillingStatusID = 2 , Name = "Paid"  },
    }

在页面加载时一次点击,然后使用SelectList环绕它。但是,我不知道应该从哪里得到它。我应该从控制器返回吗?

我对MVC很陌生,所以我只是简单地了解一下ViewModels,ViewBags和EditorFor这些概念 - 所以请回答我在回答时一无所知!!

0 个答案:

没有答案