Razor loop item index

(fairly new to Razor). The following is very pseudo-modified and extracted from my code. Maybe I don't have the correct terminology or know exactly which parts are the main and custom code.)

I want to be able to access the order / index of each element in a for-loop element. (ie in item # 1 I can refer to "1", and in item # 2 I can refer to "2", etc.). So I can use it. SORT like this (I don't care how I get it, just which I get):

item.cshtml:

@model myWidgetViewModel
<a href="foo" 
    @TrackingHelper.SetInfo(new ClickTrackInfo { 
        item = @Model.Name, 
        index= @Model.idx
    })
>
    @Model.Name
</a>

      

wrapper.cshtml

@model myWidgetViewModel
@foreach (var item in Model.myWidgetItems)
{
    @Html.Partial(item.View, item)
}

      

Conceptually, what I'm trying to do is:

@model myWidgetViewModel
@{int idx = 0;}
@foreach (var item in Model.myWidgetItems)
{
    @Html.Partial(item.View, item, idx)
    idx++;
}

      

But of course this doesn't work (@ Html.Partial only takes 2 arguments).

+3


source to share


2 answers


There are several ways to handle what you would like:

1: include a property in your partial view model :

You will need to change your partial view model regardless of the element type to have a new int type property named WidgetIndex, and then you can do this:

@model myWidgetViewModel
@{int idx = 0;}
@foreach (var item in Model.myWidgetItems)
{
    item.WidgetIndex = idx;
    @Html.Partial(item.View, item)
    idx++;
}

      

... then, in partial, you can use it:

<div>@Model.WidgetIndex</div>

      

2: put it in your watch bag (note that you can call the property anything, not just WidgetIndex:

@model myWidgetViewModel
@{int idx = 0;}
@foreach (var item in Model.myWidgetItems)
{
    ViewBag.WidgetIndex = idx;
    @Html.Partial(item.View, item)
    idx++;
}

      

... then, in partial, you can grab it:

<div>@ViewBag.WidgetIndex</div>

      



3: You can use ViewData:

@model myWidgetViewModel
@{int idx = 0;}
@foreach (var item in Model.myWidgetItems)
{
    ViewData.Add("WidgetIndex", idx);
    @Html.Partial(item.View, item)
    idx++;
}

      

in partial:

<div>@ViewData["WidgetIndex"]</div>

      

suggestions

You can use the IndexOf method instead of storing the variable (note that I used the code from solution 1 as an example):

@foreach (var item in Model.myWidgetItems)
{
    item.WidgetIndex = Model.myWidgetItems.IndexOf(item);
    @Html.Partial(item.View, item)
    idx++;
}

      

You can use RenderPartial instead of Partial for better performance:

@foreach (var item in Model.myWidgetItems)
{
    item.WidgetIndex = Model.myWidgetItems.IndexOf(item);
    @{Html.RenderPartial(item.View, item);}
    idx++;
}

      

0


source


Send a tuple to a partial

var args = new Tuple<myWidgetItemType, int>(item, idx);
@Html.Partial(item.View, args)

      

And then take that as a model in a partial (note: you are using var in your foreach loop, so it is difficult to specify the type exactly myWidgetItemType

)

@model Tuple<myWidgetItemType,int>

      

In your exact scenario, it would look like this:



wrapper.cshtml

@model myWidgetViewModel
@{
    int idx = 0;
}
@foreach (var item in Model.myWidgetItems)
{
    var args = new Tuple<myWidgetItemType, int>(item, idx++);
    @Html.Partial(item.View, args)
}

      

item.cshtml

@model Tuple<myWidgetItemType,int>
<a href="foo" 
    @TrackingHelper.SetInfo(new ClickTrackInfo { 
        item = @Model.Item1.Name, 
        index= @Model.Item2
    })
>
@Model.Item1.Name
</a>

      

0


source







All Articles