2010-11-02 35 views
7

Tôi đang làm việc trên thư viện tài nguyên tổng hợp thời gian chạy cho ASP.NET WebForms/MVC. Tôi hỗ trợ cả ASP.NET WebForms tiêu chuẩn thông qua WebControls và gần đây cũng đã thêm hỗ trợ cho ASP MVC Html Helpers. Một tính năng mà tôi hiện đang hỗ trợ với WebForms WebControls là khái niệm về các định nghĩa tài nguyên "Một phần" trong đó tài nguyên có thể được kết hợp trên các trang Cái/Xem, v.v.Trợ giúp với ASP.NET MVC Thiết kế API HtmlHelper

Khi thực hiện tương đương MVC, tôi không chắc chắn thực hành là gì? Tôi hiện đang nghiêng về phía một cái gì đó thiết kế như:

Master Page

<% using (Html.CreateCompositeResourcePartContext()) 
    { 
    Html.CompositeCssResourcePart(
     "ResourceName", 
     new[] { "/Styles/SharedStyle1.css", "/Styles/SharedStyle2.css" } 
    ); 
    %> 
    <asp:ContentPlaceHolder ID="head" runat="server"> 
    </asp:ContentPlaceHolder> 
<% } %> 

nào sẽ tạo ra một "bối cảnh" wrapper xung quanh đầu ContentPlaceHolder.

Xem trang

<asp:Content ID="HeadContentPlaceholder" ContentPlaceHolderID="head" runat="server"> 
    <% Html.CompositeCssResourcePart(
    "ResourceName", 
    new[] 
    { 
     "/Styles/PageStyle5.css", 
     "/Styles/PageStyle6.css", 
     "/Styles/PageStyle7.css" 
    }) %> 
</asp:Content> 

Vì vậy, bất kỳ trang nào xem có thể mở rộng định nghĩa tài nguyên phần như đã thấy ở trên.

Các câu hỏi tôi có:

1) Không giống như tất cả HtmlHelpers khác của tôi, các phần mở rộng không ngay lập tức viết ra các đoạn HTML mà đúng hơn là chờ đợi cho đến bối cảnh được xử lý. Các phần mở rộng này có nên tắt ViewContext thay vì (hoặc một số đối tượng khác) không?

2) Cá nhân tôi nghĩ khái niệm "sử dụng" có ý nghĩa để bao bọc một khối mã thay vì các cuộc gọi BeginCompositeResourcePartContext/EndCompositeResourcePartContext riêng biệt, bạn có đồng ý không? Nếu không, điều gì tốt hơn về các cuộc gọi phương thức riêng biệt?

Mọi phản hồi ở trên sẽ được đánh giá cao. Nếu cần thêm chi tiết, vui lòng cho tôi biết.

Sửa

... Để làm rõ khối bên trong đầu của trang Master và tài liệu tham khảo sau này ở bên một trang xem sẽ được kết hợp với nhau vào một nguồn duy nhất. Vì vậy, khi bối cảnh CompositeResourcePartContext được xử lý, tất cả SÁU tập tin được kết hợp trong chỉ ONE tập tin css và viết ra như một liên kết TAG đơn (hoặc kịch bản, css sprite vv)

<link rel="stylesheet" type="text/css" href="/MyMergedStyleSheet.css" /> 
+0

Tôi không chắc người trợ giúp này mua gì cho bạn. Đó không phải là những gì mà trình giữ chỗ nội dung dành cho vị trí đầu tiên? –

+0

@ John - Ý tưởng là mỗi cuộc gọi đến Html.CompositeCssResourcePart sẽ xác định một phần của tài nguyên tổng hợp (ví dụ:, sẽ được hợp nhất với nhau thành một tệp duy nhất khi ngữ cảnh được xử lý). Vì vậy, tôi cần một phương thức thu thập tất cả các phần trước khi thẻ liên kết/tập lệnh có thể được hiển thị khi URL được tạo ra từ tất cả các tài nguyên được tham chiếu. Có ý nghĩa? –

+0

'using' có ý nghĩa trong ngữ cảnh này, nhưng tôi không thể bình luận vượt quá điều đó. –

Trả lời

4

Sau khi cho nó một số suy nghĩ nhiều hơn (và tham khảo ý kiến ​​một đồng nghiệp) Tôi cảm thấy rằng lựa chọn tốt nhất là gắn bó với kế hoạch ban đầu của tôi về không gây ô nhiễm ASP của tôi .NET MVC API với khái niệm định nghĩa tài nguyên "một phần" (hoạt động cho WebControls, nhưng không tốt bằng MVC theo ý kiến ​​của tôi).Trước khi xem xét một phần mở rộng HtmlHelper rõ ràng cho trường hợp này trong thư viện của tôi, tôi cho rằng vấn đề này có thể được xử lý bằng cách định nghĩa một phương pháp mở rộng thông thường như sau:

public static class CustomXpediteExtensions 
{ 
    private static readonly IEnumerable<String> SharedCss = new[] 
    { 
     "/Styles/SharedStyle1.css", 
     "/Styles/SharedStyle2.css", 
     "/Styles/SharedStyle3.css" 
    }; 

    public static MvcHtmlString CustomCompositeCssResource(this HtmlHelper htmlHelper, params String[] resources) 
    { 
     return htmlHelper.CompositeCssResource(SharedCss.Concat(resources)); 
    } 
} 

Và sau đó chỉ cần tham khảo mà mở rộng thông thường (hoặc liên tục, vv .) trong trang xem.

<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server"> 
    <%= Html.CustomCompositeCssResource(
     "/Styles/PageStyle5.css", 
     "/Styles/PageStyle6.css", 
     "/Styles/PageStyle7.css" 
    ) %> 
</asp:Content> 

Điều này sẽ cho phép bạn không lặp lại chính mình khi kết hợp tài nguyên được chia sẻ (tức là đảm bảo tính nhất quán) và cuối cùng xử lý trường hợp.

Tôi sẽ để tài khoản này mở một lúc để xem có bất kỳ phản hồi nào về vấn đề này hay không; nhưng trừ khi một trường hợp tốt được thực hiện cho lý do tại sao điều này là không thể chấp nhận được, tôi nghĩ rằng đó là câu trả lời.

+0

Rực rỡ, tôi đang ăn cắp điều này .. –

2

Nó có vẻ như một ý tưởng tuyệt vời, nhưng nó có thể được phục vụ tốt hơn như là một phần của quá trình xây dựng. Bạn có thể dễ dàng tạo CSS được hợp nhất cho các trang riêng lẻ bằng cách sử dụng mẫu T4 và có lẽ quy ước đặt tên để thêm tham chiếu CSS đó vào trang của bạn. Một cái gì đó như:

<%: Html.MergedStyleSheet() %> 

thể đầu ra:

<link rel="stylesheet" type="text/css" href="/Content/ControllerName/ActionName.css" /> 
+0

Tôi đã sử dụng các tác vụ xây dựng trong quá khứ và đó chắc chắn là một tùy chọn. Lợi thế chính tôi thấy trong phương pháp thời gian chạy là bạn có thể xác định tài nguyên của mình trong mỗi trang gần như thường xuyên và có thể dễ dàng chuyển đổi giữa các chế độ rút gọn/kết hợp và gỡ lỗi mà không cần nỗ lực thêm; Ngoài ra, khi tôi xử lý CSS Sprites, cá nhân tôi thích nhìn thấy định nghĩa sprite trực tiếp trong trang đang tiêu thụ nó. Sự quan tâm của tôi là trong API được đề xuất cho kịch bản trên mà tôi chưa đề cập đến. –

Các vấn đề liên quan