2013-03-12 4 views
1

MVC 뷰에서 사용자 정의 렌더러를 람다로 정의하여 부분적으로 동일한 것을 여러 번 렌더링 할 수 있습니다. 뷰 데이터에 저장하려고합니다. 지금까지 렌더러를 저장할이 확장 메서드를 만들었습니다.MVC에서 사용자 정의 렌더러 람다를 정의 할 수 없습니다

public static class HtmlHelperExtensions 
{ 
    public static void DefineRenderer<TModel>(this HtmlHelper<TModel> html, string rendererName, Action renderer) 
    { 
     html.ViewData["_Renderer" + rendererName] = renderer; 
    } 
} 

내 뷰에서 렌더러를 정의하려고하는데 작동하지 않습니다. 내 구문이 꺼져 있다고 가정합니다. 누군가 내가 여기서 잘못하고있는 것을 말해 줄 수 있습니까? 전화했을 때 난 그냥 테스트 단락을 렌더링 할 :

@Html.DefineRenderer("AnalysisTableHeader",() => { 
    <p>test paragraph</p> 
@}); 
+0

정확히 달성하려는 것은 무엇입니까? @helper가 너에게 충분하지 않을거야? – mariozski

+1

도우미가 정확히 무엇을 기대합니까? 아,'ViewData' 대신'ViewBag'을 사용하십시오. 더 나은 방법입니다. ;) – ecampver

+0

@ e.campver 사실 나는 그 반대라고 생각합니다. 내가 할 수있을 때마다 나는 역 동성을 분명히합니다. 나는 나의 언어가 강하게 타자를 치는 것을 좋아한다. – Jez

답변

0

@ mariozski의 의견에서 영감을 얻어서 저는 일하고 싶은 행동을 얻을 수있었습니다. 렌더러로 @helper을 사용합니다. 부분에 전달하는 모델에는 도우미 렌더링의 결과가 포함됩니다. 즉, a HelperResult. 그래서 다음과 같습니다

@helper RenderHeaderTypeRow() { 
    <tr class="headerTypeRow"> 
     <td>Header type row</td> 
     <td>Goes here</td> 
    </tr> 
} 

@Html.Partial("AnalysisResponseTableContentsPartial", 
    new AnalysisResponseTableViewModel { 
     Responses = Model.OverallCaseStudyUserResponses, 
     HeaderTypeRowRenderer = RenderHeaderTypeRow() 
    } 
) 

그리고 자체가 '헤더 타입 행'과 같이 여러 번 렌더링 할 수있는 마지막 부분을 :

public class AnalysisResponseTableViewModel { 
    public HelperResult HeaderTypeRowRenderer { get; set; } 
    public List<AnalysisUserResponseViewModel> Responses { get; set; } 
} 

그런 다음, 호출도 이런 부분을 호출

@Html.Raw(Model.HeaderTypeRowRenderer.ToHtmlString()) 
@{bool reachedSummaryRows = false;} 
@foreach (var response in Model.Responses) { 
    if (!reachedSummaryRows && !response.IsPass.HasValue) { 
     reachedSummaryRows = true; 
     @:@Html.Raw(Model.HeaderTypeRowRenderer.ToHtmlString()) 
    } 

    // other table rows here 
} 
1

무효, 예를 들어,보다 다른 것을 반환해야 -method DefineRendererIHtmlString는 면도칼 @ - 구문으로 호출하거나 다른 사람이 같이 호출해야합니다

@{ 
    Html.DefineRenderer("AnalysisTableHeader",() => { 
     <p>test paragraph</p> 
    }); 
} 

편집 : 죄송합니다, 나는 renderer 매개 변수 유형 System.Action의 것을 보았다. 나는 그것이 유형 System.Func<dynamic, HelperResult>이어야합니다 생각하고 당신은 예를 들어

@{ Html.DefineRenderer("AnalysisTableHeader", @<text><p>test paragraph</p></text>); } 

를 호출해야합니다. 그런 다음 나중에 render(null).ToHtmlString()과 같이 렌더링 할 수 있습니다. 어쨌든 뷰에서 이와 같은 작업을 수행하는 경우 부분 뷰 캐싱에 문제가 발생할 수 있음에 유의하십시오.

+0

부분보기 캐싱 문제가 어떤 것인지 좀 자세히 설명해 주시겠습니까? – Jez

+0

나는 다음과 같은 일을 할 수 있습니다. 현재 렌더링되는 것과 그렇지 않은 것에 관한 것입니다. ''IHtmlString'' (MvcHtmlString.Empty)를 리턴하고''@Html.DefineRenderer ("x", ...)''를 호출하도록''DefineRenderer'' 메소드의 서명을 변경한다고 가정하십시오. 너의 견해. ''OutputCacheAttribute''를 사용할 때 시스템은 결과 HTML 태그를 캐시 (이 경우에는 빈 문자열)에 저장하고 나중에 캐시 된 결과를 제공하기 때문에''DefineRenderer'' 메서드를 호출하지 않습니다. 렌더러에 액세스하려고하자마자 ViewDataDictionary에 입력 된 적이 없으므로 실패합니다. – Peit

+0

그렇다면이 경우 내가 원하는 것을 달성하는 가장 좋은 방법은 무엇일까요? – Jez

0

아직 필요한 것은 100 % 확신 할 수 있지만 어쩌면 도움이 될 수 있습니다. 는 부분보기에 @helper 정의하고 모델의 값에 따라 렌더링하는 버전을 결정 :보기에

public enum HeaderTypes 
{ 
    AnalysisTable, 
    SomethingElse 
} 

그런 다음 코드에서 헤더 유형

선언 열거

@helper RenderHeader(HeaderTypes headerType) { 
    switch (headerType) 
    { 
     case HeaderTypes.AnalysisTable: 
      @: <p>your html</p> 
      break; 
     default: 
      @: <p>default</p> 
      break; 
    } 
} 

@RenderHeader(HeaderTypes.None) 
@RenderHeader(HeaderTypes.AnalysisTable) 

또는 문자열 값이나 다른 것을 기반으로 스위치를 수행 할 수도 있습니다.

+0

헬퍼 메서드를 부분 뷰로 전달하여 내 부분이 'RenderHeaderRow()'와 같은 식으로 호출 할 수 있고 partial을 사용하는 각 뷰가 'RenderHeaderRow'라는 도우미를 정의해야 할 수 있습니까? – Jez

+1

아마 다음과 같은 일을 할 수 있습니다 : @ Html.Partial ("PartialName", 새로운 {렌더러 = RenderCustom (HeaderTypes.AnalysisTable)}) 부분적으로 : @ Model.renderer. 그게 너에게 충분 한가? 헬퍼를 부분적으로 정의하지 않는 이유는 무엇입니까? :) – mariozski

+0

의미 상 나는 부모보기 자체에서 부모보기와 다른 마크 업을 정의하는 것이 합리적이라고 생각합니다. 그러나 귀하의 제안이 효과가있는 것처럼 보입니다. 나는 지금 그것을 개발 중이며 정제 된 해결책으로 답변을 올릴 것입니다. – Jez

관련 문제