继续这个问题foreach with index我一直试图按照以下几点做点什么:
使用扩展方法:
public static void Each<T>(this IEnumerable<T> ie, Action<T, int> action)
{
var i = 0;
foreach (var e in ie) action(e, i++);
}
使用索引在我的视图中进行迭代,并输出辅助方法的结果。
<div class="col-md-12">
@{
Model.Take(5).Each((item, n) =>
{
@RenderItem(item, n == 3);
});
}
</div
使用以下助手
@helper RenderItem(Item item, bool special = false)
{
<p>Special rendeing for special items in here</p>
}
然而吞下输出而不输出。是否有一个技巧让这个工作?
答案 0 :(得分:1)
使用此扩展方法,您不会向视图发送任何内容。 @RenderItem
的返回值永远不会发送到视图。 Razor助手是仅返回HelperResult
的函数,但您需要将此HelperResult
发送到视图。当您使用@MyHelper
调用帮助程序时,会呈现HelperResult
,因为这是@
的作用:渲染内容。
但是,当你这样做的时候:
Model.Take(5).Each((item, n) =>
{
@RenderItem(item, n == 3);
});
你只是打电话给你的助手,但不向屏幕呈现任何内容(注意结尾;)。在这种情况下,@不是渲染运算符,只是“转到Razor”开关。
您想要呈现的是.Each
的输出,但您不能,因为每个都是一个void方法。
我玩了一些你的代码,只是为了向你展示这些概念。首先,我更改了Each
方法以返回IEnumerable<HelperResult>
:
public static IEnumerable<HelperResult> Each<T>(this IEnumerable<T> ie, Func<T, HelperResult> action)
{
var i = 0;
foreach (var e in ie) yield return action(e);
}
当一个方法需要HelperResult
代码(作为Func<T,HelperResult>
)时,你可以在其上传递一个Razor表达式,所以在我的视图中我可以这样做:
@Enumerable.Range(1, 10).Each(i => @RenderItem(i, i == 3))
这将调用我的RenderItem
帮助器,但输出只是以下内容(请注意,如果在RenderItem中放置断点,断点将不会因Linq的惰性调用而命中,只需添加.ToList()在每次调用强制评估之后):
WebApplication1.FOo+<Each>d__0`1[System.Int32]
(如果您使用.ToList(),则会更改为System.Collections.Generic.List
1 [System.Web.WebPages.HelperResult]`)
这是因为Razor知道如何呈现HelperResult
而不是IEnumerable<HelperResult>
这是我们真正拥有的。
那么......我们需要做什么?是的,只需迭代结果(使用标准foreach)并显示每个结果:
@{
var x = Enumerable.Range(1, 10).Each(i => @RenderItem(i, i == 3));
foreach (var ix in x)
{
@ix
}
}
这将按预期工作,您现在逐个渲染HelperResult。
当然,这段代码只是为了展示Razor模板是如何工作的:)
希望它有所帮助。