0
votes

I have a view model that I've created with a collection (a List) of a separate model. In our database, we have two tables: BankListMaster and BankListAgentId. The primary key of the "Master" table serves as the foreign key for the Agent Id table.

As the Master/Agent ID tables have a one-to-many relationship, the view model I've created contains a List object of BankListAgentId's. On our edit page, I want to be able to both display any and all agent Ids associated with the particular bank, as well as give the user the ability to add or remove them.

I'm currently working through Steve Sanderson's blog post about editing a variable length list. However, it doesn't seem to cover this particular scenario when pulling existing items from the database.

My question is can you pass a specific collection item to a partial view, and if so how would you code that into the partial view correctly? The following code below states that

The name 'item' does not exist in the current context

However, I've also tried using a regular for loop with an index and this syntax in the partial view:

model => model.Fixed[i].AgentId

but that just tells me the name i does not exist in the current context. The view will not render using either method.

Below is the code from the view

@model Monet.ViewModel.BankListViewModel
@using (Html.BeginForm())
{
    <fieldset>
        <legend>Stat(s) Fixed</legend>
        <table>
        <th>State Code</th>
        <th>Agent ID</th>
        <th></th>
            @foreach(var item in Model.Fixed)
            {
                @Html.Partial("FixedPartialView", item)       
            }
        </table>
    </fieldset>
}

Here is the partial view

@model Monet.ViewModel.BankListViewModel

<td>
    @Html.DropDownListFor(item.StateCode,
        (SelectList)ViewBag.StateCodeList, item.StateCode)
</td>
<td>
    @Html.EditorFor(item.AgentId)
    @Html.ValidationMessageFor(model => model.Fixed[i].AgentId)
    <br />
    <a href="#" onclick="$(this).parent().remove();" style="float:right;">Delete</a>
</td>

And here is the view model. It currently initialized the Fixed/Variable agent Id lists to 10, however that is just a work-around to get this page up and running. In the end the hope is to allow the lists to be as large or small as needed.

public class BankListViewModel
{
    public int ID { get; set; }
    public string BankName { get; set; }
    public string LastChangeOperator { get; set; }
    public Nullable<System.DateTime> LastChangeDate { get; set; }

    public List<BankListAgentId> Fixed { get; set; }
    public List<BankListAgentId> Variable { get; set; }
    public List<BankListAttachments> Attachments { get; set; }

    public BankListViewModel()
    {
        //Initialize Fixed and Variable stat Lists
        Fixed = new List<BankListAgentId>();
        Variable = new List<BankListAgentId>();

        Models.BankListAgentId agentId = new BankListAgentId();

        for (int i = 0; i < 5; i++)
        {
            Fixed.Add(agentId);
            Variable.Add(agentId);

        }

        //Initialize attachment Lists
        Attachments = new List<BankListAttachments>();
        Attachments.Add(new BankListAttachments());
    }
}
3

3 Answers

2
votes

The problem is with your partial view. In your main view, in the loop, you're passing a BankListAgentId object. However, your partial view's Model type is @model Monet.ViewModel.BankListViewModel.
Furthermore, you are trying to access a variable called item in your partial view, when none exist. Instead of using item to access your data, use Model like in any other view. Each view (even a partial one) has it's own Model type.

Your partial view should look something like this:

@model Monet.ViewModel.BankListAgentId

<td>
    @Html.DropDownListFor(model => model.StateCode,
        (SelectList)ViewBag.StateCodeList, Model.StateCode)
</td>
<td>
    @Html.EditorFor(model => model.AgentId)
    @Html.ValidationMessageFor(model => model.AgentId)
    <br />
    <a href="#" onclick="$(this).parent().remove();" style="float:right;">Delete</a>
</td>
0
votes

The model you are passing into the Partial View is a BankListAgentId--- because you are looping over a collection of them when you are creating the partial view.

0
votes

You're doing everything right so far. You're looping through your list, call the partial for each list item and passing the item into the partial. It seems that the part you're missing is that when you pass the item into the partial, the item becomes the model for the partial. So you interact with it like you would in any other views, i.e. @Model.BankName, @Html.DisplayFor(m => m.BankName), etc.