2013-02-08 26 views
14

Tôi đang cố gắng hiển thị một nhóm tệp css, nhưng đầu ra bị sai thứ tự. Tôi đã thử các giải pháp @MVC4 Beta Minification and Bundling: Ordering files and debugging in browser, nhưng nó đã không giúp đỡ. Đây là gói:MVC4 StyleBundle không hiển thị gói theo đúng thứ tự

bundles.Add(new StyleBundle("~/stylesheet") 
    .Include("~/css/main.css") 
    .Include("~/css/mvc.css") 
    .Include("~/js/jquery.thickbox.css") 
    .Include("~/js/jquery.rating.css") 
    .Include("~/css/ProductListing.css") 
    .Include("~/css/dropdown/dropdown.css") 
    .Include("~/css/dropdown/dropdown.vertical.css") 
    .Include("~/js/fancybox/jquery.fancybox-1.3.1.css") 
    .Include("~/css/scartpopup.css") 
    .Include("~/css/ShoppingCart.css") 
    .Include("~/css/ceebox.css") 
    .Include("~/css/tooltip.css") 
    .Include("~/css/recent_blog_posts.css") 
    .Include("~/css/ProductDetail.css") 
    .Include("~/css/jquery-ui-1.7.3.custom.css") 
    .Include("~/css/filter_box.css") 
    .Include("~/css/custom_page.css") 
    .Include("~/css/Checkout.css") 
    .Include("~/css/CheckoutButton.css") 
); 

Và đây là kết quả, như bạn có thể thấy jquery-ui xuất hiện trên đầu.

<link href="/css/jquery-ui-1.7.3.custom.css" rel="stylesheet"/> 
<link href="/css/main.css" rel="stylesheet"/> 
<link href="/css/mvc.css" rel="stylesheet"/> 
<link href="/js/jquery.thickbox.css" rel="stylesheet"/> 
<link href="/js/jquery.rating.css" rel="stylesheet"/> 
<link href="/css/ProductListing.css" rel="stylesheet"/> 
<link href="/css/dropdown/dropdown.css" rel="stylesheet"/> 
<link href="/css/dropdown/dropdown.vertical.css" rel="stylesheet"/> 
<link href="/js/fancybox/jquery.fancybox-1.3.1.css" rel="stylesheet"/> 
<link href="/css/scartpopup.css" rel="stylesheet"/> 
<link href="/css/ShoppingCart.css" rel="stylesheet"/> 
<link href="/css/ceebox.css" rel="stylesheet"/> 
<link href="/css/tooltip.css" rel="stylesheet"/> 
<link href="/css/recent_blog_posts.css" rel="stylesheet"/> 
<link href="/css/ProductDetail.css" rel="stylesheet"/> 
<link href="/css/filter_box.css" rel="stylesheet"/> 
<link href="/css/custom_page.css" rel="stylesheet"/> 
<link href="/css/Checkout.css" rel="stylesheet"/> 
<link href="/css/CheckoutButton.css" rel="stylesheet"/> 

Làm cách nào để đảm bảo rằng biểu định kiểu được hiển thị đúng thứ tự?

+0

Tôi đã xảy ra điều này khi tôi có CSS ​​cụ thể được tham chiếu trong nhiều hơn một gói hoặc khi bao gồm nó trực tiếp trong _Layout.cshtml. – da7rutrak

+0

Nó không được tham chiếu trong nhiều hơn một gói. Phải đặt nó vào _layout.cshtml, nó được sử dụng trong tất cả các trang. Thật kỳ lạ, nếu tôi đổi tên tệp thành một thứ khác, như jqui.css, sự cố sẽ biến mất. –

+0

Tôi có nghĩa là bạn đã tham chiếu tệp CSS trực tiếp trong _Layout.cshtml, không phải là bạn đã bao gồm gói trong tệp vì điều đó đã xảy ra. – da7rutrak

Trả lời

21

Tính năng nhóm không được phép hiển thị các tệp CSS theo thứ tự chính xác, nó tuân theo một logic khác. Nếu bạn cần phải làm cho họ theo quy định, sau đó bạn nên tạo một phong tục IBundleOrderer và đặt nó là bó như người đặt hàng yêu cầu:

public class AsDefinedBundleOrderer : IBundleOrderer 
{ 
    public IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files) 
    { 
     return files; 
    } 
} 

var bundle = new StyleBundle("~/stylesheet"); 
bundle.Orderer = new AsDefinedBundleOrderer(); 
bundles.Add(bundle); 

Sau đó, điều này sẽ làm gì với danh sách do đó, Render sẽ hiển thị chính xác chúng theo cùng một thứ tự.

Cập nhật về mặc định đặt hàng

Đóng bó sử dụng khái niệm IBundleOrderer để sắp xếp các mục trong một Bundle. Lớp Bundle có nó Orderer tài sản mà trông như thế này:

public IBundleOrderer Orderer 
{ 
    get 
    { 
    if (this._orderer == null) 
     return (IBundleOrderer) DefaultBundleOrderer.Instance; 
    else 
     return this._orderer; 
    } 
    set 
    { 
    this._orderer = value; 
    this.InvalidateCacheEntries(); 
    } 
} 

Vì vậy, người đặt hàng mặc định là thực sự là một DefaultBundleOrderer cho đến khi bạn ghi đè lên nó với người đặt hàng tùy chỉnh của bạn.

Các IBundleOrderer có chữ ký sau đây:

public interface IBundleOrderer 
{ 
    IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files); 
} 

Việc thực hiện DefaultBundleOrderer này ra lệnh cho các tập tin của BundleContext, đây là một đoạn trích từ việc thực hiện OrderFiles:

foreach (BundleFileSetOrdering ordering in (IEnumerable<BundleFileSetOrdering>) context.BundleCollection.FileSetOrderList) 
    DefaultBundleOrderer.AddOrderingFiles(ordering, (IEnumerable<FileInfo>) list, fileMap, foundFiles, result); 

Vì vậy, sự khác nhau kết quả xảy ra vì điều này. Đây là khóa học không phải là một thuật toán sắp xếp ngẫu nhiên :) Các quy tắc được định nghĩa trong lớp BUndleCollection:

public static void AddDefaultFileOrderings(IList<BundleFileSetOrdering> list) 
{ 
    if (list == null) 
    throw new ArgumentNullException("list"); 
    BundleFileSetOrdering bundleFileSetOrdering1 = new BundleFileSetOrdering("css"); 
    bundleFileSetOrdering1.Files.Add("reset.css"); 
    bundleFileSetOrdering1.Files.Add("normalize.css"); 
    list.Add(bundleFileSetOrdering1); 
    BundleFileSetOrdering bundleFileSetOrdering2 = new BundleFileSetOrdering("jquery"); 
    bundleFileSetOrdering2.Files.Add("jquery.js"); 
    bundleFileSetOrdering2.Files.Add("jquery-min.js"); 
    bundleFileSetOrdering2.Files.Add("jquery-*"); 
    bundleFileSetOrdering2.Files.Add("jquery-ui*"); 
    bundleFileSetOrdering2.Files.Add("jquery.ui*"); 
    bundleFileSetOrdering2.Files.Add("jquery.unobtrusive*"); 
    bundleFileSetOrdering2.Files.Add("jquery.validate*"); 
    list.Add(bundleFileSetOrdering2); 
    BundleFileSetOrdering bundleFileSetOrdering3 = new BundleFileSetOrdering("modernizr"); 
    bundleFileSetOrdering3.Files.Add("modernizr-*"); 
    list.Add(bundleFileSetOrdering3); 
    BundleFileSetOrdering bundleFileSetOrdering4 = new BundleFileSetOrdering("dojo"); 
    bundleFileSetOrdering4.Files.Add("dojo.*"); 
    list.Add(bundleFileSetOrdering4); 
    BundleFileSetOrdering bundleFileSetOrdering5 = new BundleFileSetOrdering("moo"); 
    bundleFileSetOrdering5.Files.Add("mootools-core*"); 
    bundleFileSetOrdering5.Files.Add("mootools-*"); 
    list.Add(bundleFileSetOrdering5); 
    BundleFileSetOrdering bundleFileSetOrdering6 = new BundleFileSetOrdering("prototype"); 
    bundleFileSetOrdering6.Files.Add("prototype.js"); 
    bundleFileSetOrdering6.Files.Add("prototype-*"); 
    bundleFileSetOrdering6.Files.Add("scriptaculous-*"); 
    list.Add(bundleFileSetOrdering6); 
    BundleFileSetOrdering bundleFileSetOrdering7 = new BundleFileSetOrdering("ext"); 
    bundleFileSetOrdering7.Files.Add("ext.js"); 
    bundleFileSetOrdering7.Files.Add("ext-*"); 
    list.Add(bundleFileSetOrdering7); 
} 

Vì vậy, khi bạn gọi này từ Application_Start:

BundleConfig.RegisterBundles(BundleTable.Bundles); 

Trên thực tế bạn vượt qua những mặc định BundleCollection định nghĩa trong thư viện.

Vì vậy, chúng ta có BundleFileSetOrdering trường hợp thông qua một-by-một thành:

private static void AddOrderingFiles(BundleFileSetOrdering ordering, IEnumerable<FileInfo> files, Dictionary<string, HashSet<FileInfo>> fileMap, HashSet<FileInfo> foundFiles, List<FileInfo> result) 
{ 
    foreach (string key in (IEnumerable<string>) ordering.Files) 
    { 
    if (key.EndsWith("*", StringComparison.OrdinalIgnoreCase)) 
    { 
     string str = key.Substring(0, key.Length - 1); 
     foreach (FileInfo fileInfo in files) 
     { 
     if (!foundFiles.Contains(fileInfo) && fileInfo.Name.StartsWith(str, StringComparison.OrdinalIgnoreCase)) 
     { 
      result.Add(fileInfo); 
      foundFiles.Add(fileInfo); 
     } 
     } 
    } 
    else if (fileMap.ContainsKey(key)) 
    { 
     List<FileInfo> list = new List<FileInfo>((IEnumerable<FileInfo>) fileMap[key]); 
     list.Sort((IComparer<FileInfo>) FileInfoComparer.Instance); 
     foreach (FileInfo fileInfo in list) 
     { 
     if (!foundFiles.Contains(fileInfo)) 
     { 
      result.Add(fileInfo); 
      foundFiles.Add(fileInfo); 
     } 
     } 
    } 
    } 
} 

Kết luận

Nếu chúng ta muốn đơn giản hóa quá trình chúng ta có thể nói rằng thư viện thích một số loại file và phân loại một số tệp khác nếu có nhiều khả năng được tìm thấy. Đây là hành vi mong đợi hầu hết thời gian nhưng như bạn có thể thấy nó là easly overridable với AsDefinedBundleOrderer do đó, nó không có gì với tập tin nhất định thiết lập để thứ tự vẫn là bản gốc.

+0

Hoàn hảo, cảm ơn :) –

+1

"Nhóm không được phép hiển thị các tệp CSS theo thứ tự chính xác". Bạn đã tìm thấy thông tin này ở đâu? Tôi đang đọc hướng dẫn [ở đây] (http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification) và nó làm cho nó nghe giống như cách tiếp cận ưa thích để đảm bảo bạn có được đúng đặt hàng bằng cách thêm các tệp theo thứ tự bạn muốn. – bbak

+0

Và để làm rõ, tôi đã có cùng một vấn đề và câu trả lời của bạn đã giải quyết nó cho tôi. Tôi chỉ muốn hiểu cách thức đặt hàng cho StyleBundles hoạt động và tại sao nó có vẻ hoạt động khác với thứ tự cho ScriptBundles. Tất cả ScriptBundles của tôi đặt hàng các tệp theo cách tôi xác định mà không cần sử dụng IBundleOrderer tùy chỉnh – bbak

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