Spark-like syntax in Razor foreach
We've been using Spark view engine for a while now in our application. Since the release of Resharper 6 with its great Razor support, we've caved and started to swap over.
One of the best parts of Spark was its automatic generation of variables inside a foreach loop. For instance, inside a loop you automatically get index, last, and first variables, which let you know the index, whether the item is the first item, and whether the item is the last item respectively.
My question is as follows: i开发者_开发技巧s there a way to have a foreach automatically generate these variables for me, so I don't have to do it manually? Do I need to create my own helper that does this?
As BuildStarted suggested, I used Phil Haack's post to formulate a solution.
public static HelperResult Each<TItem>(this IEnumerable<TItem> items, Func<EnumeratedItem<TItem>, HelperResult> template)
{
return new HelperResult(writer =>
{
int index = 0;
ICollection<TItem> list = items.ToList();
foreach (var item in list)
{
var result = template(new EnumeratedItem<TItem>(index, index == 0, index == list.Count - 1, item));
index++;
result.WriteTo(writer);
}
});
}
And the EnumeratedItem class:
public class EnumeratedItem<TModel>
{
public EnumeratedItem(int index, bool isFirst, bool isLast, TModel item)
{
this.Index = index;
this.IsFirst = isFirst;
this.IsLast = isLast;
this.Item = item;
}
public int Index { get; private set; }
public bool IsFirst { get; private set; }
public bool IsLast { get; private set; }
public TModel Item { get; private set; }
}
I was forced to convert the IEnumerable to an ICollection in order to have the Count property.
Usage:
@Model.History.Each(
@<text>
<li class="@(@item.IsLast ? "last" : string.Empty)">
@{ var versionNo = Model.History.Count - @item.Index; }
<div class="clearfix version selected">
<div class="index">
<a href="@item.Item.Url">@versionNo</a>
</div>
<div class="modified">
@item.Item.DateModified<br/>
@Html.Raw(item.Item.ModifiedBy)
</div>
<div class="view">
<a href="@item.Item.CompareUrl">View changes</a>
</div>
</div>
</li>
</text>)
Phil Haack wrote a nice example that will give you the items you're looking for here http://haacked.com/archive/2011/04/14/a-better-razor-foreach-loop.aspx
It's not the same as foreach
however you'll be required to do something similar if you want the features you're looking for.
HugoWare also had a great article for IEnumerable
extensions that provides the entire functionality you're looking for http://hugoware.net/blog/build-a-smarter-loop-with-c
I would probably recommend using Hugoware's example as it's more than just razor.
in Visual Studio 2010 there are "code snippets" - code parts, which allow to generate code. with some utilityes you can edit default snippet for "foreach" and write own code, with variables you need.
精彩评论