2011-08-25 28 views
22

Tôi muốn tạo một trình trợ giúp để tôi có thể thêm nội dung giữa các dấu ngoặc giống như Helper.BeginForm(). Tôi sẽ không tạo ra một Begin, End cho helper của tôi nhưng nó khá đơn giản và dễ dàng để làm điều đó theo cách đó.Tạo Trình trợ giúp Dao cạo MVC3 như Helper.BeginForm()

cơ bản những gì tôi đang cố gắng làm là gói nội dung giữa các thẻ để họ được trả lại đã được định dạng

cái gì đó như

@using Html.Section("full", "The Title") 
{ 
This is the content for this section 
<p>More content</p> 
@Html.TextFor("text","label") 
etc etc etc 
} 

các thông số "đầy đủ" là id css cho rằng div và " tiêu đề "là tiêu đề của phần.

Có cách nào tốt hơn để đạt được điều này ngoài làm những gì tôi đang cố gắng làm không?

cảm ơn trước vì bất kỳ trợ giúp nào.

Trả lời

36

Hoàn toàn có thể. Cách này được thực hiện trong MVC với những thứ như Helper.BeginForm là hàm phải trả về một đối tượng thực hiện IDisposable.

IDisposable interface định nghĩa một phương thức gọi là Dispose được gọi ngay trước khi đối tượng được thu thập rác.

Trong C#, từ khóa using hữu ích để hạn chế phạm vi của đối tượng và để thu thập rác ngay sau khi rời khỏi phạm vi. Vì vậy, sử dụng nó với IDisposable là tự nhiên.

Bạn sẽ muốn triển khai lớp Section triển khai IDisposable. Nó sẽ phải hiển thị thẻ mở cho phần của bạn khi nó được xây dựng và hiển thị thẻ đóng khi nó được xử lý. Ví dụ:

public class MySection : IDisposable { 
    protected HtmlHelper _helper; 

    public MySection(HtmlHelper helper, string className, string title) { 
     _helper = helper; 
     _helper.ViewContext.Writer.Write(
      "<div class=\"" + className + "\" title=\"" + title + "\">" 
     ); 
    } 

    public void Dispose() { 
     _helper.ViewContext.Writer.Write("</div>"); 
    } 
} 

Hiện tại, loại có sẵn, bạn có thể mở rộng HtmlHelper.

public static MySection BeginSection(this HtmlHelper self, string className, string title) { 
    return new MySection(self, className, title); 
} 
+0

bạn nên đổi tên thành whatgoodisadispose !!! :) cảm ơn bạn rất nhiều. tôi biết bạn phải thực hiện iDisposable để cho một lớp được sử dụng với việc sử dụng {} nhưng KHÔNG BAO GIỜ nghĩ về điều này trong một giây. cảm ơn bạn rất nhiều lần nữa –

+1

Ah, Writer, điều đó đã làm điều đó. –

4

Đây là một tiện ích nhỏ mà tôi đã viết để thực hiện việc này. Nó là một chút chung chung hơn, do đó bạn có thể sử dụng nó cho bất kỳ thẻ và với bất kỳ thuộc tính. Nó được thiết lập như là một phương pháp mở rộng trên HtmlHelper để bạn có thể sử dụng nó ngay từ bên trong Razor cũng như từ bên trong mã.

public static class WrapUtil 
{ 
    public static IDisposable BeginWrap(this HtmlHelper helper, string tag, object htmlAttributes) 
    { 
     var builder = new TagBuilder(tag); 
     var attrs = GetAttributes(htmlAttributes); 
     if (attrs != null) 
     { 
      builder.MergeAttributes<string, object>(attrs); 
     } 
     helper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag)); 

     return new WrapSection(helper, builder); 
    } 

    private static IDictionary<string, object> GetAttributes(object htmlAttributes) 
    { 
     if (htmlAttributes == null) 
     { 
      return null; 
     } 
     var dict = htmlAttributes as IDictionary<string, object>; 
     if (dict != null) 
     { 
      return dict; 
     } 
     return HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
    } 

    private class WrapSection : IDisposable 
    { 
     private readonly HtmlHelper _Helper; 
     private readonly TagBuilder _Tag; 

     public WrapSection(HtmlHelper helper, TagBuilder tag) 
     { 
      _Helper = helper; 
      _Tag = tag; 
     } 

     public void Dispose() 
     { 
      _Helper.ViewContext.Writer.Write(_Tag.ToString(TagRenderMode.EndTag)); 
     } 
    } 
} 
Các vấn đề liên quan