开发者

How to implement foreach delegate in razor viewengine?

The following code works for webform view engine.

<% Model.Categories.ForEach(x => { %>
    <li><a href="#">@x.Name</a></li>
<% }) %>

I wrote the above code as below in razor view:

@Model.Categories.ForEach(x => {
  <li><a href="开发者_StackOverflow社区#">@x.Name</a></li>
})

But this doesn't work.

Can anyone suggest, Is there any way to achieve this in razor view?

Thanks in advance.


Is there any reason you need to do that?

@foreach(var x in Model.Categories) {
    <li><a href="#">@x.Name</a></li>
}

Above does the exact same thing, and is more idiomatic.

I can't see a way to output the .ForEach() delegate result using the Razor syntax. Razor expects called methods or invoked properties to return a value, which is then emitted into the view output. Because .ForEach() doesn't return anything, it doesn't know what to do with it:

Cannot explicitly convert type 'void' to 'object'

You can have the iterator index quite tersely like so:

@foreach (var item in Model.Categories.Select((cat, i) => new { Item = cat, Index = i })) {
   <li><a href="#">@x.Index - @x.Item.Name</a></li>
}

If you want to define this as an extension method, instead of an anonymous type, you can create a class to hold the Item, Index pair, and define an extension method on IEnumerable<T> which yields the items in the original enumerable wrapped in this construct.

public static IEnumerable<IndexedItem<T>> WithIndex<T>(this IEnumerable<T> input)
{ 
    int i = 0;
    foreach(T item in input)
        yield return new IndexedItem<T> { Index = i++, Item = item };
}

The class:

public class IndexedItem<T>
{
    public int Index { get; set; }
    public T Item { get; set; }
}

Usage:

@foreach(var x in Model.Categories.WithIndex()) {
    <li><a href="#">@x.Index - @x.Item.Name</a></li>
}


Thanks for your help. I found how to implement delegates in Razor based on the following article by Phil Haack. Templated Razor Delegates

Here is the extension code for IEnumerable:

public static HelperResult ForEachTemplate<TEntity>(
        this IEnumerable<TEntity> items, 
        Func<RowEntity<TEntity>, HelperResult> template)
{
    return new HelperResult(writer =>
               {
                   var index = 0;
                   foreach (var item in items)
                   {
                       template(new RowEntity<TEntity> { 
                               Index = index, 
                               Value = item }).WriteTo(writer);
                       index++;
                   }
               });
}

public class RowEntity<TEntity>
{
    public int Index { get; set; }
    public TEntity Value { get; set; }
}

View Model is :

// IEnumerable<Person>

public class Person
{
    public string Name { get; set; }
}

And the use of that extension methods:

@Model.ForEachTemplate(@<p>Index: @item.Index Name: @Item.Value.Name</p>)
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜