2014-02-18 97 views
0

从这个问题foreach with index我一直试图做的大意如下的东西继:输出被吞噬在Razor视图

使用扩展方法:

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> 
} 

但是输出吞噬,而不是输出。有没有一个窍门让这个工作?

回答

1

使用此扩展方法,您不会向视图发送任何内容。 @RenderItem的返回值永远不会发送到视图。剃刀助手是简单返回HelperResult的函数,但您需要将此HelperResult发送到视图。当您使用@MyHelper调用帮助器时,会呈现HelperResult,因为这就是@所做的:呈现内容。

但是,当你正在做的:

Model.Take(5).Each((item, n) => 
     { 
      @RenderItem(item, n == 3); 
     }); 

你打电话是你的助手,但是没有渲染任何内容到屏幕(注意结尾)。在这种情况下,@不是渲染操作符,只是“去剃刀”开关。 你可能想渲染的是.Each的输出,但是你不能这样做,因为每个都是无效的方法。

我玩了一下你的代码,只是为了向你展示这些概念。首先,我改变了你的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>),你可以通过剃刀表达就可以了,所以在我看来,我可以这样做:

@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]`)

这是因为剃刀如何呈现一个HelperResult但不是IEnumerable<HelperResult>这就是我们真正拥有的。

那么...我们需要做什么?是的,只要遍历结果(使用标准的foreach),并显示每个结果:

@{ 
    var x = Enumerable.Range(1, 10).Each(i => @RenderItem(i, i == 3)); 
    foreach (var ix in x) 
    { 
     @ix 
    } 
} 

,将工作如预期,你现在是由一个渲染你的HelperResult之一。

当然,这个代码只是为了显示剃刀如何使用模板的工作:)

希望它能帮助。