2012-01-31 3 views
10

이것이 가능한지 확실하지 않지만이 방법을 쉽게 찾을 수 있는지 확인할 것입니다.MVC 3 면도기, 사용자 정의 마크 업/도우미가있는 도우미

첫째, 나는 다음과 같습니다 내 사이트에 몇 가지 반복 마크 업이 있습니다

<div class="module"> 
    <h3>Title</h3> 
    <div> 
     <p>Information goes here</p> 
    </div> 
</div> 

내가 뭘 원하는 내가 이런 일을 할 수 있도록 도우미/섹션의 일종이를 마무리하다 이 렌더링 될 때

@MyHelper("This is my Title") { 
    <p>Here is my custom markup</p> 
} 

그런 다음, 상기와 <h3></h3> div에의 맞춤 마크의 파라미터를 통해 통과시켜 표제를 삽입한다. 사용자 정의 마크 업은 테스트에서부터 폼 컨트롤, 부분 뷰에 이르기까지 다양합니다. 이게 가능한 것입니까?

답변

12

글쎄, 여기에 HTML 헬퍼 확장을 사용하여 뭔가를 가까이하는 "표준"방법이 있습니다. Html.BeginForm()의 간단한 버전입니다.

접근법 : IDisposable을 반환하고 using 문을 나머지 부분을 처리하도록합니다.

이것은 개념의 예입니다 (작동하지만). 즉각적인 재사용을 목적으로하지 않습니다. 생산 코드가 아닌 많은 단축키로 신속하게 작성되고 개선 및 최적화를위한 많은 기회가 있으며 바보 같은 실수가있을 수 있으며 TagBuilder 등을 사용할 수 있습니다. 다른 래퍼 클래스를 재사용하기 위해 쉽게 수정할 수 있습니다 (심지어 ASP.NET MVC에 이미 일반적인 것 - 하나 필요하지 않은).

public static class WrapHelper 
{ 
    private class Wrapper : IDisposable 
    { 
     private bool disposed; 
     private readonly TextWriter writer; 

     public Wrapper(HtmlHelper html) 
     { 
      this.writer = html.ViewContext.Writer; 
     } 

     public void Dispose() 
     { 
      if (disposed) return; 

      disposed = true; 

      writer.WriteLine(" </div>"); 
      writer.WriteLine("</div>"); 
     } 
    } 

    public static IDisposable Wrap(this HtmlHelper html, string title) 
    { 
     TextWriter writer = html.ViewContext.Writer; 

     writer.WriteLine("<div class=\"module\">"); 
     writer.WriteLine(" <h3>" + html.Encode(title) + "</h3>"); 
     writer.WriteLine(" <div>"); 

     return new Wrapper(html); 
    } 
} 

사용법 :

@using (Html.Wrap("Title")) 
{ 
    <p>My very own markup.</p> 
} 
+0

이것은 내가 찾고있는 것입니다. – Josh

+0

http://stackoverflow.com/questions/7196276/creating-mvc3-razor-helper-like-helper-beginform에서보다 간단한 예제가 있습니다. –

+0

솔루션을 정확히 고려할 때 무엇이 ​​더 단순한 지 보는 데 어려움을 겪습니다. same ...이 예제의 유일한 추가 코드는 질문의 요구 사항을 충족시키기위한 것입니다. 그리고 Dispose의 부작용을 피하기위한 기초적인 검사는 두 번 호출됩니다. – JimmiTh

0

당신이 App_Code 폴더 안에 갈 것 빠른 도우미 메서드를 작성하는 면도기와 MVC 3 진짜 쉬운를 사용하는 경우,

(나는 그것을 MyHtmlHelpers 이름을 것이다)

나는 조금 다른 조금 뭔가를 시도 할 것입니다 쉽게 같은 :

@helper myTemplate(string title, string markup){ 
    <div class="module"> 
     <h3>@title</h3> 
     @markup 
    </div> 
} 

그리고 방법 당신 U에게 .cshtml 파일의 내용은 다음과 같습니다.

@MyHtmlHelpers.myTemplate('title','markup') 

정확하게 이해하면 작동합니다.

+1

마크 업을 문자열 매개 변수로 사용하지 않으려 고합니다. 내보기에서 마크 업을 일반 HTML로 사용하고 싶기 때문입니다. 내가 뭘 찾고 MVC 3 도우미와 흉내 낸다 MVC 2에서 <% (Html.Beginform()) {%> html 마크 업 <% } %> ' – Josh

3

@The 카네다, 통찰력에 감사드립니다. PartialView 이름을 제공하고 파싱하는 방법을 알고있는 것처럼 아이디어를 작성하고 확장했습니다.

<Extension()> _ 
Public Function UseTemplate(ByVal html As HtmlHelper, ByVal PartialView As String) As IDisposable 
    Return New TemplateWrapper(html, PartialView) 
End Function 

Public Class TemplateWrapper 
    Implements IDisposable 

    Private _HtmlHelper As HtmlHelper 

    'Index 0 is header 
    'Index 1 is footer 
    Private _TemplateWrapper As String() 

    Public Sub New(ByVal Html As HtmlHelper, ByVal PartialView As String) 

     _TemplateWrapper = Html.Partial(PartialView).ToHtmlString.Split("@@RenderBody()") 

     _HtmlHelper = Html 
     _HtmlHelper.ViewContext.Writer.Write(_TemplateWrapper(0)) 

    End Sub 

    Public Sub Dispose() Implements IDisposable.Dispose 

     _HtmlHelper.ViewContext.Writer.Write(_TemplateWrapper(1).Substring(12)) 

    End Sub 

End Class 

가네다의 예와 같은 사용법을 사용하십시오. 부분보기에서는 @RenderBody()를 호출하는 대신 내용의 가운데 부분에 대한 플래그 역할을하는 @RenderBody()를 넣으십시오. VB 번역 죄송합니다.

내 용도의 예를 사용합니다.

Using Html.UseTemplate("ContentWrapper") 

    @Html.EditorFor(Function(m) m.Var1, "TemplateHint") 
    @Html.EditorFor(Function(m) m.Var2, "TemplateHint") 
    @Html.EditorFor(Function(m) m.Var3) 

End Using 

내 부분은 다음과 같습니다.

<div class="content"> 
    @@RenderBody() 
</div> 
15

일회용 트릭을 사용하지 않고 다른 방법으로도 작업이 약간 필요하며 작은 도우미에게는 좋습니다.

@MyHelper("This is my Title", 
    @<p>Here is my custom markup</p> 
) 

또는 여러 라인 :이 도우미의

@helper MyHelper(string title, Func<object, object> markup) { 
    <div class="module"> 
     <h3>Title</h3> 
     <div> 
      <p>@markup.DynamicInvoke(this.ViewContext)</p> 
     </div> 
    </div> 
} 

사용법은 다음과 같습니다

@MyHelper("This is my Title", 
    @<text> 
     <p>More than one line</p> 
     <p>Of markup</p> 
    </text> 
) 
Telerik MVC 컨트롤은 귀하의 자바 스크립트 코드를 추가 할 수 있도록하기 위해 예를 들어,이 트릭을 사용

문서로드

여기도 멋진 example입니다. 또한 약간의 정보 here이 있습니다.

+0

나는이 예제를 좋아해요. 구현하기가 훨씬 쉬워 보입니다. 한 가지 문제를 해결하도록 도와 줄 수 있습니까? MyHelper 메서드가 정적이기 때문에 this.ViewContext가 컴파일되지 않습니다 (적어도 필자의 도우미에서 설정 한대로). –

+1

놀랍게도 null을 전달하면 잘 작동하는 경향이 있지만 충돌이 발생할 수있는 복잡한 시나리오가있을 수 있습니다. 어쨌든 Htmlhelper 객체를 통해 ViewContext에 액세스 할 수 있어야합니다 (정적 메서드가 html 확장 메서드 인 경우에는 ViewContext 속성을 사용하여 액세스해야합니다). 그렇지 않은 경우, 메소드에 ViewContext를 수동으로 전달할 수 있습니다. – slawek

+0

응답 해 주셔서 감사합니다. 합격하면 null이됩니다. 내 코드가 ViewContext에 액세스 할 수없는 이유는 응용 프로그램 대신 MVC 사이트를 작성하기 때문입니다. 지금 일하고있다. 나는 당신의 대답이 단순하고 효과적이기 때문에 최선이라고 믿습니다. –