2014-02-18 69 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之一。

當然,這個代碼只是爲了顯示剃刀如何使用模板的工作:)

希望它能幫助。