asp.net mvc - pass partial data model to partial view
Asked Answered
E

2

8

I wish to build a partial view that gets a model column and print it. Something like that:

At the view:

@model IEnumerable<products_comparison.Models.Product>
@{
ViewBag.Title = "Index";

var Brand = (from r in Model
             select r.Brand).Distinct();
}
<h2>
Index</h2>

@Html.RenderPartial("_DisplayAttribute",Brand)

And at the partial view:

<table>
    <tr>
        <th>
            Brand
        </th>
    </tr>
    @foreach (var row in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(r => row)
            </td>
        </tr>
    }
</table>

There are a few problems I run into:

  1. The compiler doesnt allow me to send Barnd to the partial view.
  2. If you look at the partial view code you will see the word Brand, which is the column name. I dont wish to hard-coded the word "Brand" in the partial view, instead I like that the column name will be there.
  3. In the partial view I need to put @model products_comparison.Models.Product, but I dont want to send the hole table. I want to send only one column - But I dont know what to put there..

Thanks!

EDIT:

Just to clear one thing, I want that the view will call the same partial view for each column in the table(for most of the columns in the table anyway) and each time I'll send a different column(distinct value column to be exact).

Excitor answered 4/1, 2012 at 9:51 Comment(0)
F
12

Start by refactoring and putting the right logic into the right place. This LINQ query has strictly nothing to do in a view. A view is not supposed to do any LINQ queries or whatever to pull data. A view is supposed to work with data that it is passed to it from the controller action under the form of a view model. A controller action builds and passes an adapted view model that you define for the view.

So as always you start by defining a view model that will be adapted to the requirements of your view:

public class MyViewModel
{
    public IEnumerable<Brand> Brands { get; set; } 
}

then you write a controller action that will populate this view model and pass it to the view:

public ActionResult Foo()
{
    IEnumerable<products_comparison.Models.Product> products = ...
    var model = new MyViewModel
    {
        Brands = (from r in Model select r.Brand).Distinct()
    };
    return View(model);
}

then a view:

@model MyViewModel
<table>
    <tr>
        <th>
            Brand
        </th>
    </tr>
    @Html.DisplayFor(x => x.Brands)
</table>

and finally you could define a corresponding display template which will automatically be rendered for each element of the Brands collection of your view model (~/Views/Shared/DisplayTemplates/Brand.cshtml):

@model Brand
<tr>
    <td>
        @Html.DisplayForModel()
    </td>
</tr>
Frigidaire answered 4/1, 2012 at 10:0 Comment(4)
Thank you. My problem with your answer is that the view address to the Brand column and not to a column.. I want that the view will call the same partial view for each column in the table(for most of the columns in the table). Because of that I didnt passed only the brand to the view, rather I send the hole table.Excitor
@nir, in this case you could adapt your view model so that it contains the columns and the rows of the table.Frigidaire
So how it deffer from the model itself?Excitor
@nir, that will depend on how you want to present the information on the view.Frigidaire
C
7

For 1 try changing @Html.RenderPartial("_DisplayAttribute",Brand) to @Html.Partial("_DisplayAttribute",Brand)

You will also need to specify the model in the partial view like @model products_comparison.Models.Brand or something like it

Also please clarify 2 & 3 as they are not clear what you want

Christinchristina answered 4/1, 2012 at 9:56 Comment(1)
@Excitor It's typically helpful if you 'Accept' the answer that helped you. (Please and Thank You.)Syllabub

© 2022 - 2024 — McMap. All rights reserved.