开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜